BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Tom
Super User Tom
Super User

If you use the code that I posted to loop over all characters variables and translate CR or LF to spaces you can easily adjust it to also translate the tabs into spaces. Just add one more character to both the TO and FROM arguments to the TRANSLATE() function. The hex code for a tab is '09'x.

Tom
Super User Tom
Super User

Here is a simplied version of what I posted before that will write all of the files in one data step.  That makes both the code generation easier and the execution faster.

First get the contents and divide into groups.  Note that with this verison the sort by VARNUM is critical since postional variable lists (A -- B) will be used later to write the columns. You can change the upper bound of 1000 in the DO loop to control how many variables are written to each file. The lower bound of three is to allow room for the two id variables at the front.

proc contents data=have out=contents(keep=varnum name) noprint ; run;
proc sort data=contents;
  where lowcase(name) not in ('studyid','partnum');
  by varnum;
run;
data files ;
  group+1;
  do col=3 to 1000 ;
    set contents;
    output;
  end;
run;

Now use this file to both write the header lines to each of the output files and also write the code needed to write the data lines. Modify the statement that creates the FNAME variable to match your file naming requirement. Note the inclusion of the MOD option in the generated FILE statements. That is because the header line will already be written be this step and the step that writes the data just needs to append to the existing files. Also note it is using a line length of 1,000,000 which should be more than enough for 1,000 variables as long as they aren't all extremely long character variables.  SAS can support longer line lengths, but it might depend on your operating system.

filename code temp;
data _null_;
   set files ;
   by group ;
   fname = cats('outfile',group,'.csv');
   file csv filevar=fname dsd lrecl=1000000 ;
   if first.group then put 'studyid,partnum,' @;
   put name @ ;
   if last.group then put ;
   file code ;
   if first.group then put
    / 'file ' fname :$quote. 'dsd mod lrecl=1000000;'
    / 'put ( studyid partnum ' name '-- ' @
   ;
   if last.group then put name ') (+0);' ;
run

Now write the data lines. Notice that the included code only had the FILE and PUT statements so the rest of the data step is just plain code that should be easier to edit.  I included loops to handle both the special missing value issue and blanking out tabs, cr and lf characters. I used two SET statements to force STUDYID and PARTNUM to the beginning of the data vector so that the postional variable lists will not include them.  I used the INDSNAME= option on the second SET just to make sure there was at least one character variable defined for the _character_ variable list used in the array definition. I also used the DO OVER style loops that SAS is trying to remove from the documentation. It is just so much easier to not have to code indexes for operations that you want to apply to all members of an array.

data _null_;
  set have (keep=studyid partnum);
  set have (drop=studyid partnum) indsname=__C__;
  array __C _character_;
  array __N _n_ _numeric_;
  do over __C ; __C=translate(__C,'   ','090A0D'x); end;
  do over __N ; if missing(__N) then __N=.; end;
  %include code / source2 ;
run;

 

rfarmenta
Obsidian | Level 7

Thank you, Tom! This new code is definitely more efficent. This is exactly what I needed and I appreciate your help.

 

One last question, I am being asked to remove commas that may exist in character values as well. Can I just use this modified version of what you wrote:

 

do over __C ; __C=translate(__C,'   ','002C'x); end;

 

I am not sure that is the right HEX code for commas though.

 

Thank you again!

Tom
Super User Tom
Super User
'2C'x is the right code for a comma. But you could also use '00'x||',' as to specify the two character string of a binary zero and a comma.

Thank you, Tom! This new code is definitely more efficent. This is exactly what I needed and I appreciate your help.

One last question, I am being asked to remove commas that may exist in character values as well. Can I just use this modified version of what you wrote:

do over __C ; __C=translate(__C,' ','002C'x); end;

I am not sure that is the right HEX code for commas though.

rfarmenta
Obsidian | Level 7

I just did some additional checks of my data and there apprears to be an issue with the CSV files that are being created. Some of the variable names are not being matched up correctly with the data. For example, the data for BMI and weight are reversed so the BMI variable has the weight values and the weight variable has the BMI values.

 

Do you know what might be going on to make this happen?

 

Thank you!

 

rfarmenta
Obsidian | Level 7

Tom-I just did a check and the previous code you sent does not seem to have the issue of data being stored under the wrong variable name. Thank you again!

 

Tom
Super User Tom
Super User
This could happen if the dataset used to write the header row is not sorted in the proper VARNUM order. So if the variables in the actual data set are in the order is A,BMI,HT,B and the list of variable names used to write the header row is in the order A,HT,BMI,B then the header will write 'A,HT,BMI,B' and the variable list A-B will mean 'A BMI HT B'.
Make sure the dataset use in the last step that writes the file headers and code to write the data lines is sorted by GROUP and VARNUM.

I just did some additional checks of my data and there apprears to be an issue with the CSV files that are being created. Some of the variable names are not being matched up correctly with the data. For example, the data for BMI and weight are reversed so the BMI variable has the weight values and the weight variable has the BMI values.


rfarmenta
Obsidian | Level 7

Ok Thank you! I tried a couple different sorts and am stil lending up with the same issue. I am going to try a few other things. Thank you again!

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 22 replies
  • 5697 views
  • 7 likes
  • 4 in conversation