02-18-2014 09:56 AM
I am trying to use the following macro to append two datasets that have the same variable names, but some of the character variables have different lengths in the two data sets:
49 %macro union(dsn1=,whcd dsn2=,whjv out=
49 ! workinghourscd_jv_combined);
ERROR: Expecting comma (to separate macro parameters) or close
parenthesis (to end parameter list) but found: dsn2
ERROR: A dummy macro will be compiled.
51 proc contents data=&dsn1 noprint
54 proc contents data=&dsn2 noprint
58 data _null_;
59 file "workinghourscd_jv_combined.sas";
60 merge out1 out2 end=last;
61 by ID;
62 if _n_ = 1 then put "Data &out;";
63 l = max(length,length2);
64 if last then do;
65 put " set &dsn1 &dsn2;";
66 put "run;";
70 %include "workinghourscd_jv_combined.sas";
72 %mend union;
02-18-2014 10:28 AM
I don't see the macro call, so perhaps is that why it isn't executed...?
Impossible to help if you don't share the log with the errors. It seems you have more than one problem?
02-18-2014 10:46 AM
sorry, isn't the %macro union(dsn1=workinghourscd, dsn2=workinghoursjv, out= workinghourscd_jv_combined); the macro call?
No, that is the start of definition. To excute a macro you would have something like
%union(dsn1=workinghourscd, dsn2=workinghoursjv, out= workinghourscd_jv_combined);
You're going to need a lot more work if your goal is to remove the warning about mismatched lengths. If all of the longer variables are in one dataset the quick and dirty approach would be to place that dataset name first on the SET statement and ignore the warning. Otherwise you will want to create a Length statement that appears beforethe Set statement.
02-18-2014 11:08 AM
Thanks, I will remove the "macro" bit.
My goal is to automate it, so that SAS looks at the two data sets and chooses the longest length of the same variables to append.
02-18-2014 01:36 PM
Something like this will put the character variables into a list suitable for use in a length statement in a data step
The DSN1 and 2 must resolve to be in upper case, if they are in separate libraries than you need to modify the parameters to include both libraries, (lib1=, lib2= for example), make similar %upcase assignment, in the comparison (libname in ("&lib1","&lib2")) and the set statement, set &lib1..&dsn1 &lib2..&dsn2 ;
Note the value for the comparison TYPE='char' , char must be lower case as that is how this is stored in the dictionary table.
%macro stack (lib=, dsn1=, dsn2=, outset=);
/* create table varlengths as*/
select string into :varlengths separated by ' '
select catx(' $ ',name,MAX(length)) as string
where libname="&LIB" and memname in ("&DSN1","&DSN2")
group by name)
length &varlengths ;
and to execute somethingl like:
%stack (lib=work, dsn1=set1, dsn2=set2, outset=combinedset);