The program is:
%macro loop(testcd=);
data data2;
set data;
if %scan(&testcd.,1) eq 1 %if %length(&testcd.) gt %length(%scan(&testcd.,1)) %then %do; and %scan(&testcd.,2) eq 1 %end; then do;
value=1;
end;
else if %scan(&testcd.,1) eq 0 %if %length(&testcd.) gt %length(%scan(&testcd.,1)) %then %do; and %scan(&testcd.,2) eq 0 %end; then do;
value=0;
end;
run;
%mend;
%loop(testcd=%str(Indx55));
%macro loop2(testcd=);
data aa;
set data;
a=%scan(&testcd.,1);
b=%length(%scan(&testcd.,1));
run;
%mend;
%loop2(testcd=%str(Indx55));
The program creates a new column VALUE, my question is that what does the if loop mean? I only know the form like
if xx then do; xxx; end;
or
%if xx %then %do; xxx; %end;
But it is
if xx %if xx %then %do; and xxx %end; then do; end;
which seems abnormal in syntax. But it did run successfully. Does anyone know how to understand this program ?
The data and the data2 in the above program are like this,
data -
AVISIT INDX55
Week2 0
Week4 0
Week8 1
Week12 1
...
data2 -
Another question is that why %scan(&testcd.,1)=the value of Indx55, while %length(%scan(&testcd.,1))=6? (see %loop2 above)
Hello @Sally_Caffrey,
@Sally_Caffrey wrote:
I only know the form like
if xx then do; xxx; end;
or
%if xx %then %do; xxx; %end;
These two structures are sufficient to understand the code if you consider in addition that
So, with your example macro call
%loop(testcd=%str(Indx55));
in the first phase:
The resulting SAS code passed to the DATA step compiler for further processing in the second phase is:
data data2;
set data;
if Indx55 eq 1 then do;
value=1;
end;
else if Indx55 eq 0 then do;
value=0;
end;
run;
(It could be simplified, e.g., by omitting do; and end;. Also, an IN condition could be used: if Indx55 in (0, 1) then value=Indx55;).
Similarly, with a macro call like
%loop(testcd=%str(Indx55,Indx66));
the %IF condition is met (13 gt 6) and the resulting SAS code looks like this:
data data2;
set data;
if Indx55 eq 1 and Indx66 eq 1 then do;
value=1;
end;
else if Indx55 eq 0 and Indx66 eq 0 then do;
value=0;
end;
run;
In the DATA step code generated by macro %LOOP2, called as %loop2(testcd=%str(Indx55));, the statements
a=Indx55;
b=6;
are interpreted as usual: variable a is assigned the value of variable Indx55 and variable b the constant value 6. Again, the timing -- first resolution of macro code, then compilation of DATA step code -- is important.
There is no actual loop. And so the macro name is misleading. This code assigns a value of either zero or one to the new variable named VALUE, depending on whether or not certain IF conditions are satisfied. That's all it does is see if the conditions are met. This code seems like a very difficult way to code something that doesn't need to be that difficult.
Hello @Sally_Caffrey,
@Sally_Caffrey wrote:
I only know the form like
if xx then do; xxx; end;
or
%if xx %then %do; xxx; %end;
These two structures are sufficient to understand the code if you consider in addition that
So, with your example macro call
%loop(testcd=%str(Indx55));
in the first phase:
The resulting SAS code passed to the DATA step compiler for further processing in the second phase is:
data data2;
set data;
if Indx55 eq 1 then do;
value=1;
end;
else if Indx55 eq 0 then do;
value=0;
end;
run;
(It could be simplified, e.g., by omitting do; and end;. Also, an IN condition could be used: if Indx55 in (0, 1) then value=Indx55;).
Similarly, with a macro call like
%loop(testcd=%str(Indx55,Indx66));
the %IF condition is met (13 gt 6) and the resulting SAS code looks like this:
data data2;
set data;
if Indx55 eq 1 and Indx66 eq 1 then do;
value=1;
end;
else if Indx55 eq 0 and Indx66 eq 0 then do;
value=0;
end;
run;
In the DATA step code generated by macro %LOOP2, called as %loop2(testcd=%str(Indx55));, the statements
a=Indx55;
b=6;
are interpreted as usual: variable a is assigned the value of variable Indx55 and variable b the constant value 6. Again, the timing -- first resolution of macro code, then compilation of DATA step code -- is important.
Don't write code like that. Just because you can, does not mean you should. When I worked as a SAS developer, I wrote macros that were thousands of lines long and were callable by other macros that were even longer. There were many macro statements, macro functions, and macro variables. Still, my first rule of macro writing was NEVER use the macro language where you don't have to, and equivalently, ALWAYS use ordinary SAS instead when you can. In a DATA step, that means access the macro variables when you can via SYMGET, process their values in ordinary DATA step variables by using ordinary DATA step statements and functions, and if necessary, send the results into macro variables via SYMPUTX.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.