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-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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