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

Good morning.  I have defined variable names in %let statements, but am having trouble trying to resolve part that cycles through a %do loop.  Here is the simplified version:

 

%let vars=%nrstr(var&n._x var&n._y); 

%macro datapull;

data want;

set have;

keep %do n=1 %to 10; &vars %end;;

run;

%mend;

 

The macro runs fine if I substitute in all of the variable names by hand - meaning entering each variation 10 times. I've tried using different forms of %nrstr, %superq, etc, but just can't figure this one out.  Do I need to define the %let statement in it's own macro?  I've also tried putting the %do n1-10 %end statement in the %let statement as well.  I feel like I'm missing something easy here.  What is it?

 

I'd like to keep this format - I know the obvious way is to just type out all the variable names.

 

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

Hello @JenniferBernard,

 

The %NRSTR function avoids the warning about &n not being resolved by adding invisible macro quoting characters to the macro variable value. To get rid of these added characters in the %DO loop, where they would cause errors, use the %UNQUOTE function:

keep %do n=1 %to 10; %unquote(&vars) %end;;

If those variables in the KEEP statement are contained in dataset HAVE, you may want to replace the KEEP statement with a KEEP= dataset option to improve performance:

set have(keep=%do n=1 %to 10; %unquote(&vars) %end;);

View solution in original post

9 REPLIES 9
JenniferBernard
Obsidian | Level 7

Okay, I've seemed to resolve this by just having

%let vars=var&n._x var&n._y;

 

The macro works and completes, but the log gives the warning that the reference isn't resolved.  I think this might be okay?

PaigeMiller
Diamond | Level 26

@JenniferBernard wrote:

Okay, I've seemed to resolve this by just having

%let vars=var&n._x var&n._y;

 

The macro works and completes, but the log gives the warning that the reference isn't resolved.  I think this might be okay?


It doesn't sound okay to me. Can you run this command before you run the macro,

 

options mprint;

then run the macro again and show us the ENTIRE log for the macro (all of it, do not pick and choose parts of the log to show us).

--
Paige Miller
JenniferBernard
Obsidian | Level 7

The warning comes from the &n. not being resolved in the let statement (outside the macro).

 

I checked with mprint and it did indeed resolve to include all of my variables.

PaigeMiller
Diamond | Level 26

Adding:

 

naming variables like var1_x var1_y var2_x var2_y and so on makes your programming more difficult. If, on the other hand you had named your variables varx_1 vary_1 varx_2 vary_2 then your programming is much easier.

 

Your KEEP statement can then be reduced to

 

keep varx_1-varx_10 vary_1-vary_10;

or even simpler (if appropriate)

 

keep varx: vary:;

no macros needed 

--
Paige Miller
JenniferBernard
Obsidian | Level 7

Yes, 100% agree.  Can't do anything with this set-up however.

Tom
Super User Tom
Super User

Best solution is to go back to the drawing board and make sure to place the numeric sequence at the END of the variable names.  Then you can skip any need for code generation.

 

Sounds like you need a macro tool that takes three inputs.

%macro varlist(base,count,suffix);
%local i j ;
%do i=1 %to &count;
  %do j=1 %to %sysfunc(countw(&suffix,%str( )));
 &base.&i%scan(&suffix,&j,%str( ))
  %end;
%end;
%mend ;

Example:

400   %put %varlist(var,10,_x _y);
var1_x  var1_y  var2_x  var2_y  var3_x  var3_y  var4_x  var4_y  var5_x  var5_y  var6_x  var6_y  var7_x  var7_y  var8_x  var8_y
var9_x  var9_y  var10_x  var10_y

 Note if you are using this inside of a macro you might need to add something to prevent the parser from getting confused by the macro function call in the middle of the variable name.  So something like:

%macro varlist(base,count,suffix);
%local i j ;
%do i=1 %to &count;
  %do j=1 %to %sysfunc(countw(&suffix,%str( )));
 %unquote(&base.&i%scan(&suffix,&j,%str( )))
  %end;
%end;
%mend ;
FreelanceReinh
Jade | Level 19

Hello @JenniferBernard,

 

The %NRSTR function avoids the warning about &n not being resolved by adding invisible macro quoting characters to the macro variable value. To get rid of these added characters in the %DO loop, where they would cause errors, use the %UNQUOTE function:

keep %do n=1 %to 10; %unquote(&vars) %end;;

If those variables in the KEEP statement are contained in dataset HAVE, you may want to replace the KEEP statement with a KEEP= dataset option to improve performance:

set have(keep=%do n=1 %to 10; %unquote(&vars) %end;);
JenniferBernard
Obsidian | Level 7
Great! Thank you so much! And I've moved the keep statement, so thank you for that.
ballardw
Super User

Here is a way to see what values you are currently creating:

%let vars=%nrstr(var&n._x var&n._y); 

%macro dummy;
%do n=1 %to 10;
%put resolved variables: &vars ;
%end;

%mend;

%dummy;

And what may be one way to create what you are expecting:

%macro dummy2(vars=var&n._x var&n._y);
%do n=1 %to 10;
%put resolved variables: &vars ;
%end;

%mend;

%dummy2;

 

Note since I am using the %put statement it does need the ; to end the statement. If you want/need a single Keep statement then your current structure would work while passing the parameter this way. Or create multiple Keep statements. Since you are not using a data set option multiple keeps will work:

data junk;
   set sashelp.class;
   keep name;
   keep age;
run;

 

 

I am not a fan of just letting a macro parameter, your Vars variable, just appear in the middle of a macro. It is often hard to tell just when a value is assigned or used and debugging scope problems gets much more difficult.

 

 

 

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
  • 9 replies
  • 718 views
  • 4 likes
  • 5 in conversation