BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
sophia_SAS
Obsidian | Level 7
Hi SAS users!
 
I have 3 flags: flag_REF1, flag_REF2, flag_REF3 and where each flag is noted (=1), then I want to void that corresponding REF value. So in short I'm trying to produce the following steps but in a local macro:
1. flag_REF1=1 then REF1=.;
2. flag_REF2=1 then REF2=.;
3. flag_REF3=1 then REF3=.;
 
However, it's not working. Any thoughts on where I'm going wrong?
 
data want;
set have;

options mprint;
%macro loop;
 %local i;
  %do i=1 %to 3;
 
%if flag_REF&i=1 %then %do; REF&i=.; %end;
 
 %end;
%mend loop;
%loop;
 
Thanks!
 
run;
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Make sure the macro is generating the SAS code you want to run.

To make your program easier to understand define the macro BEFORE starting the data step where you are going to CALL the macro.

%macro loop;
%local i;
%do i=1 %to 3;
if flag_REF&i=1 then REF&i=.;
%end;
%mend loop;

options mprint;
data want;
  set have;
 %loop;
run;

View solution in original post

10 REPLIES 10
PaigeMiller
Diamond | Level 26

Are flag_ref1 flag_ref2 flag_ref3 data set variables or macro variables? Are ref1 ref2 and ref3 data set variables or macro variables?

 

Where are their values set?

 

If they are data set variables, please look at the data set HAVE with your own eyes to see if they have the values you expect them to have. If they are macro variables, please use the %PUT command to look at the values contained by these macro variables; do they have the values that you expect them to have?

 

Don't use the phrase "it's not working". We can't ever help you with such limited information. Explain what is not working and how you know that. Please show us the SAS log, first add OPTIONS MPRINT; to the first line of your code and then run it again, and provide us the log by clicking on the {i} icon and paste the log as text into the window that appears. Do not skip this step.

--
Paige Miller
Tom
Super User Tom
Super User

Are you trying to change the values of variables in a data set? Or the values of macro variables?

novinosrin
Tourmaline | Level 20

Hello @sophia_SAS  You should ideally avoid macros and use arrays instead. However, if you really want to use macros your logic should be

 

%macro loop;
 %local i;
  %do i=1 %to 3;
 
  if flag_REF&i=1 then REF&i=.;
 
 %end;
%mend loop;
%loop
Tom
Super User Tom
Super User
Why would you want to introduce macro quoting by using the %STR() macro function?
novinosrin
Tourmaline | Level 20

Sir sorry,I edited coz i wanted to see the generated statements in the log 🙂

 

%macro loop;
 %local i;
  %do i=1 %to 3;
 
%put %str( if flag_REF&i=1 then REF&i=.;); 
 
 %end;
%mend loop;
%loop
 if flag_REF1=1 then REF1=.;
 if flag_REF2=1 then REF2=.;
 if flag_REF3=1 then REF3=.;

I generally do that to see what's happening, but you caught me too fast before I could edit like a cop:)

sophia_SAS
Obsidian | Level 7

Hi Novinosrin,

 

Thank you for your solution! This was what I was looking for. To get to your point about using an array vs a macro. My actual code contains around 50 variables that follow this same pattern. To avoid all of that additional coding, I thought a macro would be better than an array.  But maybe not?  Why do you suggest I avoid a macro for this example?

 

Thanks again!

Tom
Super User Tom
Super User

Make sure the macro is generating the SAS code you want to run.

To make your program easier to understand define the macro BEFORE starting the data step where you are going to CALL the macro.

%macro loop;
%local i;
%do i=1 %to 3;
if flag_REF&i=1 then REF&i=.;
%end;
%mend loop;

options mprint;
data want;
  set have;
 %loop;
run;
sophia_SAS
Obsidian | Level 7

Thanks for your solution. I really like the suggestion to define the macro before the data step. This is something I don't regularly do, but will now!

 

ballardw
Super User

If the variables involved are all data set variables then no need for macros. That is the sort thing array processing is designed for.

 

data want;
   set have;
   array frf flag_ref1 - flag_ref3;
   array  rf ref1 - ref3;
   do i=1 to dim(frf);
      if frf[i]=1 then call missing(rf[i]);
   end;
   drop i;
run;

The code savings would be more obvious if there were 50 of each variable though.

sophia_SAS
Obsidian | Level 7

Thanks for your response.  Yes, all the variables involved, i.e. flag_ref1 - flag_ref3, ref1 - ref3 are data set variables.  However, in my actual code there are close to 50 variables that follow this same pattern. To avoid all of that additional coding, I thought a macro would be better than an array.  However, maybe there are unintended issues with using the macro? 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 10 replies
  • 1141 views
  • 1 like
  • 5 in conversation