BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
EC27556
Quartz | Level 8

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.)));
1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

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.))))

View solution in original post

6 REPLIES 6
maguiremq
SAS Super FREQ

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();
EC27556
Quartz | Level 8

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!

FreelanceReinh
Jade | Level 19

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.))))
Tom
Super User Tom
Super User

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: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 6 replies
  • 1136 views
  • 3 likes
  • 5 in conversation