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;
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.
Are you trying to change the values of variables in a data set? Or the values of macro variables?
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
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:)
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!
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;
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!
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.
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?
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.