<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Preventing truncation of dataset when merging PROC JSON output(s) in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851859#M336730</link>
    <description>&lt;P&gt;It seems very strange to me that all of those variables would have a maximum length of 75.&lt;/P&gt;
&lt;P&gt;But it does make writing the code easier.&amp;nbsp; Just add the LENGTH statement before the SET statement in the data step that combines the individual datasets.&amp;nbsp; Note you probably also need to remove any formats that might be attached (I suspect that the JSON engine is like the ORACLE and XLSX engine and is stupdily attaches $xx formats to character variables that do not need them.).&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
  length SUBJECTID ......  $75 ;
  set fin: ;
  format _character_ ;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You could type out all of the names or since you have them in a dataset pull the list from there into a macro variable and use the macro variable.&lt;/P&gt;
&lt;P&gt;The advantage of typing them (or copy and pasting them from a printout) is that you can put them into some logical order (such as having the SUBJECTID first) so that when you browse the dataset it is easier to review.&lt;/P&gt;</description>
    <pubDate>Mon, 02 Jan 2023 20:01:39 GMT</pubDate>
    <dc:creator>Tom</dc:creator>
    <dc:date>2023-01-02T20:01:39Z</dc:date>
    <item>
      <title>Preventing truncation of dataset when merging PROC JSON output(s)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851779#M336688</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am currently using a PROC HTTP request to GET a JSON payload from a server. The response is:&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;1. Too long to be pulled in one request and must be pulled and concatenated page by page.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;2. Contains two data sets (data, data_recorddata) that must be merged together on their corresponding observation.&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;3. Dynamic in the respect that I cannot anticipate what variables are coming across the API to have a JSON map set up.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My issue is that at some point when I merge the data sets or concatenate the pages together I end up truncating some of the data contained in the observations. How do I prevent this? Can I set some parameter so that SAS does not look at length or automatically sets the longest possible length? Unfortunately I cannot anticipate exactly what will come through the API and need to be flexible but also cannot truncate. I have provided my current code below which will pull from the API and perform merging and concatenating of the JSON payload. Any help is greatly appreciated!&lt;CODE class=""&gt;&lt;/CODE&gt;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;/*Extract the total number of pages from JSON response and assessbles url for each page */
		data urls;
		set api.pagination;
		call symputx("nobs", sum(totalPages, -1));
		do I = 0 to totalPages;
			path = catt(&amp;amp;base_url., &amp;amp;study_name., '/', &amp;amp;endpoint., '?size=500&amp;amp;pages=',I, '&amp;amp;filter=formKey==', &amp;amp;crf.);
			output;
		end;
		run;
		
		/*Create macro variables for url paths*/
		data _NULL_;
		set urls nobs=obs;
		call symput("iter", url);
		run;
		
		
		/*Loop through urls based on number of urls and collect API data for each page*/
		%do I = 0 %to &amp;amp;nobs.;
			%let ping = &amp;amp;url.%str(&amp;amp;)page=&amp;amp;I.;
			%put &amp;amp;ping;
			proc http
		   		url= "&amp;amp;ping."
		   		method="GET"
		   		out=respAll
		   		proxyhost="http://webproxy-azuse.vsp.sas.com"
		   		proxyport=3128
		   		headerout=hdrs;
			 	headers
			   		"x-imn-security-key"= &amp;amp;security_key.
			   		"x-api-key"= &amp;amp;api_key.;
			
			
			/*Assign http response to JSON library*/
			/*Makes dataset in work library for parsed data set*/
			data data_page&amp;amp;I.;
				libname page&amp;amp;I. JSON fileref=respAll;
				set page&amp;amp;I..data;
			run;
				
			proc datasets lib=page&amp;amp;I.; quit;
			
			/*Makes dataset in work library for parsed column recorddata set*/
			data recorddata_page&amp;amp;I.;
				set page&amp;amp;I..data_recorddata;
			run;
			
			/*Merge the two datasets so patient info and CRF data are on same page. Merge by index by page*/
			data mergeData&amp;amp;I.;
				merge work.data_page&amp;amp;I. work.recorddata_page&amp;amp;I.;
				drop ordinal_recordData;
				by ordinal_data;
			run;
			
			proc transpose data=mergeData&amp;amp;I. out=middle&amp;amp;I.;
				var _all_;
			run;
			
			proc transpose data=middle&amp;amp;I. out=mergeDataFin&amp;amp;I. (drop=_name_ _label_);
			var _all_;
			run;
			
			data mergeDataFin&amp;amp;I.;
				set mergeDataFin&amp;amp;I.;
				if _N_ = 1 then delete;
			run;
	
			libname page&amp;amp;I. clear;
	
		%end;
		run;
	
		data out.&amp;amp;output.;
			set mergeDataFin: truncover;
&lt;BR /&gt;			drop ordinal_root ordinal_data;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Seen below, there is truncation at the formId, recordId, and deleted columns when looking at the finalized dataset.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Capture.PNG" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/78971iACA733A516C431EF/image-size/large?v=v2&amp;amp;px=999" role="button" title="Capture.PNG" alt="Capture.PNG" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 01 Jan 2023 23:16:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851779#M336688</guid>
      <dc:creator>bdighera</dc:creator>
      <dc:date>2023-01-01T23:16:33Z</dc:date>
    </item>
    <item>
      <title>Re: Preventing truncation of dataset when merging PROC JSON output(s)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851782#M336691</link>
      <description>&lt;P&gt;If you want the DATASETS created from the JSON text to be consistently defined then create your own MAP and pass it to the JSON engine using the MAP= option.&lt;/P&gt;</description>
      <pubDate>Mon, 02 Jan 2023 05:17:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851782#M336691</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2023-01-02T05:17:48Z</dc:date>
    </item>
    <item>
      <title>Re: Preventing truncation of dataset when merging PROC JSON output(s)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851786#M336693</link>
      <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Patrick_0-1672638061262.png" style="width: 665px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/78972iB05A4DB6127FECF5/image-dimensions/665x22?v=v2" width="665" height="22" role="button" title="Patrick_0-1672638061262.png" alt="Patrick_0-1672638061262.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;If you can't know the possible universe of variables then how can you write downstream code that consumes this data and does something useful with it?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;What you could do instead of a map:&amp;nbsp;&lt;/P&gt;
&lt;P&gt;1. Read the individual JSON's into individual SAS tables with a common root name&lt;/P&gt;
&lt;P&gt;2. Query dictionary.columns to determine all the column names with their max. lengths from all the tables and create a mapping table with it (or alternatively an attrib statement for all the columns).&lt;/P&gt;
&lt;P&gt;3. Concatenate the tables via a data step set statement with the mapping table first in the list - or alternatively the generated attrib statement before the set statement.&lt;/P&gt;</description>
      <pubDate>Mon, 02 Jan 2023 05:46:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851786#M336693</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2023-01-02T05:46:14Z</dc:date>
    </item>
    <item>
      <title>Re: Preventing truncation of dataset when merging PROC JSON output(s)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851848#M336727</link>
      <description>&lt;P&gt;Hi Patrick,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you for your response. I have build a preliminary mapping table using dictionary.columns and a proc sql statement, but now I am unsure how to modify/format my current preliminary mapping table to concatenate with the other tables.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My variables are in the name column. Should I transpose this? How would I assign the max_length and type? Thanks again for your help.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;So far, I build a general map using:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;proc sql ;
		create table length_report as
		select upcase(name) as NAME
		       , count(*) as n_datasets
		       , max(length) as max_length
		       , min(length) as min_length
		       , count(distinct length) as n_lengths
		       , min(type) as min_type
		       , max(type) as max_type
		       , count(distinct type) as n_types
		from dictionary.columns
		where upcase(LIBNAME) = "FIN"
		group by 1
		order by 1;
		quit;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Capture.PNG" style="width: 582px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/78981iB4FF863753A6EE68/image-size/large?v=v2&amp;amp;px=999" role="button" title="Capture.PNG" alt="Capture.PNG" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 02 Jan 2023 17:22:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851848#M336727</guid>
      <dc:creator>bdighera</dc:creator>
      <dc:date>2023-01-02T17:22:44Z</dc:date>
    </item>
    <item>
      <title>Re: Preventing truncation of dataset when merging PROC JSON output(s)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851859#M336730</link>
      <description>&lt;P&gt;It seems very strange to me that all of those variables would have a maximum length of 75.&lt;/P&gt;
&lt;P&gt;But it does make writing the code easier.&amp;nbsp; Just add the LENGTH statement before the SET statement in the data step that combines the individual datasets.&amp;nbsp; Note you probably also need to remove any formats that might be attached (I suspect that the JSON engine is like the ORACLE and XLSX engine and is stupdily attaches $xx formats to character variables that do not need them.).&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
  length SUBJECTID ......  $75 ;
  set fin: ;
  format _character_ ;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;You could type out all of the names or since you have them in a dataset pull the list from there into a macro variable and use the macro variable.&lt;/P&gt;
&lt;P&gt;The advantage of typing them (or copy and pasting them from a printout) is that you can put them into some logical order (such as having the SUBJECTID first) so that when you browse the dataset it is easier to review.&lt;/P&gt;</description>
      <pubDate>Mon, 02 Jan 2023 20:01:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851859#M336730</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2023-01-02T20:01:39Z</dc:date>
    </item>
    <item>
      <title>Re: Preventing truncation of dataset when merging PROC JSON output(s)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851879#M336734</link>
      <description>&lt;P&gt;You could do something along the line of below sample code.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql;
  create table work.attribs as
  select 
    upcase(name) as _gname,
    max(varnum) as varnum,
    max(name) as name,
    max(length) as len,
    max(case when type='char' then '$' else ' ' end) as type,
    max(format) as format,
    max(informat) as informat,
    max(case when missing(label) then ' ' else cats("'",label,"'") end) as label
  from dictionary.columns
  where 
    libname='SASHELP'
    and memname like 'CLASS%'
  group by _gname
  order by varnum, _gname
  ;
quit;

filename codegen temp;
data _null_;
  file codegen;
  set work.attribs end=_last;
  if _n_=1 then put 'attrib';
  put name 'length=' type len @;
  if not missing(format)    then put 'format=' format @;
  if not missing(informat)  then put 'informat=' informat @;
  if not missing(label)     then put 'label=' label @;
  put;
  if _last then put ';';
run;

data want;
  %include codegen /source2;
  set sashelp.class:;
run;
filename codegen clear;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Ordering by varnum to keep the variable order in the pdv closer to the source data.&lt;/P&gt;
&lt;P&gt;Ordering by varnum and name in case varnum is missing like for source data stored in a data base.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 03 Jan 2023 02:23:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Preventing-truncation-of-dataset-when-merging-PROC-JSON-output-s/m-p/851879#M336734</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2023-01-03T02:23:17Z</dc:date>
    </item>
  </channel>
</rss>

