Obsidian | Level 7

How to understand this consecutive if loop embedded %if loop

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)

1 ACCEPTED SOLUTION

Accepted Solutions

Re: How to understand this consecutive if loop embedded %if loop

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

1. in a first phase, the macro processor resolves all macro code (%scan(), &testcd., %length(), %if ... %then, %do/%end, etc.)
2. in the second phase, the resulting SAS code is processed (here: the DATA step is compiled and executed).

So, with your example macro call

``%loop(testcd=%str(Indx55));``

in the first phase:

• &testcd. is replaced by Indx55
• then %scan(Indx55,1) is replaced by Indx55 (the first word in the string "Indx55")
• %length(Indx55) is replaced by 6 (the length of the string "Indx55")
• the resulting %IF condition 6 gt 6 evaluates to FALSE, which means that the %DO-%END block following %then is not executed, i.e., the SAS code and ... eq 1 is not generated.

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.

6 REPLIES 6
Diamond | Level 26

Re: How to understand this consecutive if loop embedded %if loop

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.

--
Paige Miller
Obsidian | Level 7

Re: How to understand this consecutive if loop embedded %if loop

Thanks PaigeMiller. Yes I agree with you, this program can be simplified to simple data step.

Re: How to understand this consecutive if loop embedded %if loop

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

1. in a first phase, the macro processor resolves all macro code (%scan(), &testcd., %length(), %if ... %then, %do/%end, etc.)
2. in the second phase, the resulting SAS code is processed (here: the DATA step is compiled and executed).

So, with your example macro call

``%loop(testcd=%str(Indx55));``

in the first phase:

• &testcd. is replaced by Indx55
• then %scan(Indx55,1) is replaced by Indx55 (the first word in the string "Indx55")
• %length(Indx55) is replaced by 6 (the length of the string "Indx55")
• the resulting %IF condition 6 gt 6 evaluates to FALSE, which means that the %DO-%END block following %then is not executed, i.e., the SAS code and ... eq 1 is not generated.

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.

Obsidian | Level 7

Re: How to understand this consecutive if loop embedded %if loop

Thanks for such detailed explanation FreelanceReinh! Now I am clear how this loop works.
Rhodochrosite | Level 12

Re: How to understand this consecutive if loop embedded %if loop

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.

Obsidian | Level 7

Re: How to understand this consecutive if loop embedded %if loop

Thanks for introduction WarrenKuhfeld. I agree SYMGET is better and will try.
Discussion stats
• 6 replies
• 226 views
• 1 like
• 4 in conversation