Hi All,
I am trying to write a short macro for the regression model, where I need to create a string for the class variable for proc logistics. I have the following information:
%let Catvariable = Sex Race RUCC Treatment;
%let Reference = F W U P;
I want to create a string from the above information, which can be used in the class row of the proc logistics as follows:
Sex (ref = 'F') Race (ref= 'W') RUCC (ref='U') Treatment ('P');
I would greatly appreciate any thoughts.
Thanks,
sandyzman1
Seems simple enough, just use a %DO loop.
Let's try it by making a macro that takes those two inputs and emits the values.
%macro model(catvariable,reference);
%local i ;
%do i=1 %to %sysfunc(countw(&catvariable,%str( )));
%scan(&catvariable,&i,%str( )) (ref="%scan(&reference,&i,%str( ))")
%end;
%mend;
And let's try it with your example values:
8 %let string=%model(Catvariable = Sex Race RUCC Treatment,Reference = F W U P); 9 %put &=string; STRING=Sex (ref="F") Race (ref="W") RUCC (ref="U") Treatment (ref="P")
If you want to put the %DO loop in the middle of larger macro then just use a %LET statement in the middle of the %DO loop instead.
%do i=1 %to %sysfunc(countw(&catvariable,%str( )));
%let string=&string %scan(&catvariable,&i,%str( )) (ref="%scan(&reference,&i,%str( ))");
%end;
Seems simple enough, just use a %DO loop.
Let's try it by making a macro that takes those two inputs and emits the values.
%macro model(catvariable,reference);
%local i ;
%do i=1 %to %sysfunc(countw(&catvariable,%str( )));
%scan(&catvariable,&i,%str( )) (ref="%scan(&reference,&i,%str( ))")
%end;
%mend;
And let's try it with your example values:
8 %let string=%model(Catvariable = Sex Race RUCC Treatment,Reference = F W U P); 9 %put &=string; STRING=Sex (ref="F") Race (ref="W") RUCC (ref="U") Treatment (ref="P")
If you want to put the %DO loop in the middle of larger macro then just use a %LET statement in the middle of the %DO loop instead.
%do i=1 %to %sysfunc(countw(&catvariable,%str( )));
%let string=&string %scan(&catvariable,&i,%str( )) (ref="%scan(&reference,&i,%str( ))");
%end;
Hi @Tom,
Thank you so much for the macro. It worked perfectly. However, as you suggested, when I use the %DO loop (below) in the middle of a larger macro using a %LET statement.
%do i=1 %to %sysfunc(countw(&catvariable,%str( )));
%let string=&string %scan(&catvariable,&i,%str( )) (ref="%scan(&reference,&i,%str( ))");
%end;
It gave me the following error.
WARNING: Apparent symbolic reference STRING not resolved.
ERROR: The text expression &STRING. SEX (REF="F") contains a recursive reference to the macro variable
STRING. The macro variable will be assigned the null value.
Do you have any suggestions? Thanks.
Add
%local string;
to your macro before the %DO loop.
It defines the macro variable, and avoids unpleasant side-effects.
Make sure STRING is defined BEFORE trying to reference its value.
So either set it to an empty string before the %DO loop.
%let string=;
Or define it as a LOCAL macro variable (which will also start as empty.)
%local string;
Or you might want to do both, depending on whether you want to reuse STRING multiple times in the macro code.
Parallel lists are hard to manage. I suggest using a lookup object. In this case an INFORMAT.
%macro
main
(
Catvariable = Sex Race RUCC Treatment,
Reference = RACE=W RUCC=U TREATMENT=P SEX=F ABC=2 XYZ=1
);
proc format;
invalue $ref(upcase just) &reference;
run;
%local i w;
%do i = 1 %to %sysfunc(countw(%superq(catvariable)));
%let w = %scan(%superq(catvariable),&i);
%put NOTE: CLASS &w(ref=%sysfunc(inputc(&w,$ref),$quote.));
%end;
%mend main;
%main;
NOTE: CLASS Sex(ref="F" ) NOTE: CLASS Race(ref="W" ) NOTE: CLASS RUCC(ref="U" ) NOTE: CLASS Treatment(ref="P" )
I would probably define the INFORMAT outside the MACRO but you get the idea. It would be helpful to know the big picture.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.