I'm trying to run something with the same logic as below. Basically, I want the macro 'Test' to insert the where statement and then resolve 'i' after it has done this as part of the do loop.
Instead it seems to be resolving 'i' whilst it is in the macro definition.
I know it is possible to do because I have just taken this macro out of a larger macro where it was running fine. (have moved out to improve efficiency)
Any help as to how to make 'i' not resolve until macro variable 'a' has been inserted into the code is much appreciated!
%macro Test(a); %do i=4 %to 6; data test&i.; set sashelp.cars&a.; run; %end; %mend Test; %Test((where=(cylinders=&i.)));
Hello @EC27556,
You can mask the ampersand in the macro call using the %NRSTR function and unmask it in the macro code using the %UNQUOTE function:
%macro Test(a); %do i=4 %to 6; data test&i.; set sashelp.cars%unquote(&a.); run; %end; %mend Test; %Test(%nrstr((where=(cylinders=&i.))))
Why are you conducting a subsetting WHERE in a macro parameter? That doesn't really make sense to me, and it eliminates the warning when you include the subsetting on the SET statement.
%macro test(a);
%do i = 4 %to 6;
data test&i.;
set sashelp.cars (where = (cylinders = &i.));
run;
%end;
%mend test;
%test();
Basically I oversimplified things.
My real problem is more like the below
%macro Test(c,b,a); %do i=4 %to 6; data &c.&i.; set sashelp.&b.&a.; run; %end; %mend Test; %Test(First,Cars,(where=(cylinders=&i.)));
%Test(Second,Cars,(where=(Cylinder_test=&i. and cylinder_true=&i.)));
Basically i want 6 datasets - First4, First5, First6, Second4, Second5, Second6. But the second datasets come from a dataset that is laid out slightly differently and needs a different where statement - because different variable names etc..
I could just write out 2 datasteps with different where statements however in my actual code i am creating hundreds of datasets so not really feasible - well it is it would just be a massive ugly program.
The best was of doing this i thought was to create a where statement as a macro variable and insert back into the code. Then it just takes up 1 line of space.
Probably not the best way of doing what i need to do but it's how my brain has framed the problem - in any case, someone has worked a solution below!
What are you trying to accomplish here? 🙂
Hello @EC27556,
You can mask the ampersand in the macro call using the %NRSTR function and unmask it in the macro code using the %UNQUOTE function:
%macro Test(a); %do i=4 %to 6; data test&i.; set sashelp.cars%unquote(&a.); run; %end; %mend Test; %Test(%nrstr((where=(cylinders=&i.))))
You are a genius, thank you 🙂
The simplest way is to add single quotes around the value in the call and then use %SYSFUNC() to call DEQUOTE() to remove them.
%macro Test(dsnopts);
%do i=4 %to 6;
data test&i.;
set sashelp.cars( %sysfunc(dequote(&dsnopts%str( ))));
run;
%end;
%mend Test;
options mprint;
%Test(dsnopts='where=(cylinders=&i)');
%test;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.