I am trying to sort several datasets in SAS using a loop within a macro, using a list of numbers, some of which have leading zeros, within dataset names (eg., in the example code, a list of 01,02
), and this code will also guide some other loops I would like to build.
I used the SAS guidance on looping through a nonsequential list of values with a macro DO loop code as a starting point from here: http://support.sas.com/kb/26/155.html.
data dir1201;
input compid directorid X;
format ;
datalines;
01 12 11
02 15 5
;
run;
data dir1202;
input compid directorid X;
format ;
datalines;
01 12 1
03 18 8
;
run;
%macro loops1(values);
/* Count the number of values in the string */
%let count=%sysfunc(countw(&values));
/* Loop through the total number of values */
%do i = 1 %to &count;
%let value=%qscan(&values,&i,%str(,));
proc sort data=dir12&value out=dir12sorted&value nodupkey;
by directorid compid;
run;
%end;
%mend;
options mprint mlogic;
%loops1(%str(01,02))
I assume str
is needed for nonsequential lists, but that is also useful when I want to retain leading zeros;
I see the macro variable seems to incorporate the 01 or 02 in the log, but then I receive the error 22 and 200 right afterward. Here is a snippet of the log error using this example code:
339 %macro loops1(values);
340 /* Count the number of values in the string */
341 %let count=%sysfunc(countw(&values));
342 /* Loop through the total number of values */
343 %do i = 1 %to &count;
344 %let value=%qscan(&values,&i,%str(,));
345 proc sort data=dir12&value out=dir12sorted&value nodupkey;
346 by directorid compid;
347 run;
348 %end;
349 %mend;
350 options mprint mlogic;
351 %loops1(%str(01,02))
MLOGIC(LOOPS1): Beginning execution.
MLOGIC(LOOPS1): Parameter VALUES has value 0102
MLOGIC(LOOPS1): %LET (variable name is COUNT)
MLOGIC(LOOPS1): %DO loop beginning; index variable I; start value is 1; stop value is 2; by
value is 1.
MLOGIC(LOOPS1): %LET (variable name is VALUE)
NOTE: Line generated by the macro variable "VALUE".
1 dir1201
--
22
--
200
ERROR: File WORK.DIR12.DATA does not exist.
I don't understand why dir1201
is showing, but then the error is referencing the dataset work.dir12
(ignoring the 01
)
The macro quoting is confusing the parser into thinking the macro quoting signals the start of a new token. You can either add %unquote()
to remove the macro quoting.
proc sort data=%unquote(dir12&value) out=%unquote(dir12sorted&value) nodupkey;
Or just don't add the macro quoting to begin with.
%let value=%scan(&values,&i,%str(,));
It will be much easier to use your macro if you design it to take space delimited values rather than comma delimited. Then there is no need to add macro quoting to the call either.
%macro loops1(values);
%local i value ;
%do i = 1 %to %sysfunc(countw(&values,%str( )));
%let value=%scan(&values,&i,%str( ));
proc sort data=dir12&value out=dir12sorted&value nodupkey;
by directorid compid;
run;
%end;
%mend loops1;
%loops1(values=01 02)