DATA Step, Macro, Functions and more

%IF-%THEN-%ELSE behavior with %DO (iterative)

Reply
New Contributor
Posts: 4

%IF-%THEN-%ELSE behavior with %DO (iterative)

I have a macro which uses a %DO statement to run a datastep four times. Each time, I set the variable "var" equal to the value contained in the array "letters" at the index of &i. I then use this datastep variable "var" as the condition for my %IF-%THEN-%ELSE statement. See below:


%macro test2;

data c1;
a='a';
b='b';
c='';
d='d';
run;

%do iterator = 1 %to 4;
data c2;
set c1;
array letters (4) $25 a b c d;
x=&iterator;
var=strip(letters);
put +5 "Iteration Number:" x +3 "var=" var;

%if var = 'b' %then %do;
put "WARNING-" +4 "The macro condition was true!!!";
put;
%end;
%else %do;
put "ERROR-" +4 "The macro condition was false!!!";
put;
%end;

run;

%end;
%mend;

%test2;



The problem I am having is that the %if statement always evaluates the same (either true or false) for all 4 iterations of the datastep c2. My output is below:



MLOGIC(TEST2): Beginning execution.
MPRINT(TEST2): data c1;
MPRINT(TEST2): a='a';
MPRINT(TEST2): b='b';
MPRINT(TEST2): c='';
MPRINT(TEST2): d='d';
MPRINT(TEST2): run;

NOTE: The data set WORK.C1 has 1 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds


MLOGIC(TEST2): %DO loop beginning; index variable ITERATOR; start value is 1; stop value is 4; by value
is 1.
MPRINT(TEST2): data c2;
MPRINT(TEST2): set c1;
MPRINT(TEST2): array letters (4) $25 a b c d;
SYMBOLGEN: Macro variable ITERATOR resolves to 1
MPRINT(TEST2): x=1;
MPRINT(TEST2): var=strip(letters);
MPRINT(TEST2): put +5 "Iteration Number:" x +3 "var=" var;
MLOGIC(TEST2): %IF condition var = 'b' is FALSE
MPRINT(TEST2): put "ERROR-" +4 "The macro condition was false!!!";
MPRINT(TEST2): put;
MPRINT(TEST2): run;

Iteration Number:1 var=a
The macro condition was false!!!

NOTE: There were 1 observations read from the data set WORK.C1.
NOTE: The data set WORK.C2 has 1 observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds


MLOGIC(TEST2): %DO loop index variable ITERATOR is now 2; loop will iterate again.
MPRINT(TEST2): data c2;
MPRINT(TEST2): set c1;
MPRINT(TEST2): array letters (4) $25 a b c d;
SYMBOLGEN: Macro variable ITERATOR resolves to 2
MPRINT(TEST2): x=2;
MPRINT(TEST2): var=strip(letters);
MPRINT(TEST2): put +5 "Iteration Number:" x +3 "var=" var;
MLOGIC(TEST2): %IF condition var = 'b' is FALSE
MPRINT(TEST2): put "ERROR-" +4 "The macro condition was false!!!";
MPRINT(TEST2): put;
MPRINT(TEST2): run;

Iteration Number:2 var=b
The macro condition was false!!!

NOTE: There were 1 observations read from the data set WORK.C1.
NOTE: The data set WORK.C2 has 1 observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds


MLOGIC(TEST2): %DO loop index variable ITERATOR is now 3; loop will iterate again.
MPRINT(TEST2): data c2;
MPRINT(TEST2): set c1;
MPRINT(TEST2): array letters (4) $25 a b c d;
SYMBOLGEN: Macro variable ITERATOR resolves to 3
MPRINT(TEST2): x=3;
MPRINT(TEST2): var=strip(letters);
MPRINT(TEST2): put +5 "Iteration Number:" x +3 "var=" var;
MLOGIC(TEST2): %IF condition var = 'b' is FALSE
MPRINT(TEST2): put "ERROR-" +4 "The macro condition was false!!!";
MPRINT(TEST2): put;
MPRINT(TEST2): run;

Iteration Number:3 var=
The macro condition was false!!!

NOTE: There were 1 observations read from the data set WORK.C1.
NOTE: The data set WORK.C2 has 1 observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.07 seconds
cpu time 0.01 seconds


MLOGIC(TEST2): %DO loop index variable ITERATOR is now 4; loop will iterate again.
MPRINT(TEST2): data c2;
MPRINT(TEST2): set c1;
MPRINT(TEST2): array letters (4) $25 a b c d;
SYMBOLGEN: Macro variable ITERATOR resolves to 4
MPRINT(TEST2): x=4;
MPRINT(TEST2): var=strip(letters);
MPRINT(TEST2): put +5 "Iteration Number:" x +3 "var=" var;
MLOGIC(TEST2): %IF condition var = 'b' is FALSE
MPRINT(TEST2): put "ERROR-" +4 "The macro condition was false!!!";
MPRINT(TEST2): put;
MPRINT(TEST2): run;

Iteration Number:4 var=d
The macro condition was false!!!

NOTE: There were 1 observations read from the data set WORK.C1.
NOTE: The data set WORK.C2 has 1 observations and 6 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds


MLOGIC(TEST2): %DO loop index variable ITERATOR is now 5; loop will not iterate again.
MLOGIC(TEST2): Ending execution.


As you can see from the log output, the %IF condition fails in all four iterations.. however I had expected it to be true for the second iteration as var=b during the second iteration. Can anyone shed some light here on what is really going on and where my misunderstanding might be?


Thanks,
Brian
Super Contributor
Super Contributor
Posts: 3,174

Re: %IF-%THEN-%ELSE behavior with %DO (iterative)

The SAS program you posted appears to be mixing DATA step logic and MACRO code logic, which is not supported. You can see from the SAS-generated MLOGIC log messages that any attempt to reference a SAS DATA step variable from a MACRO language statement will not work - the string is treated as character data.

When attempting to use the MACRO LANGUAGE, it's best to get a working program defined and tested -- then determine how, if at all, you may see the MACRO language helping with your particular SAS environment / operational processing requirements.

Scott Barry
SBBWorks, Inc.
New Contributor
Posts: 4

Re: %IF-%THEN-%ELSE behavior with %DO (iterative)

So the condition for %IF must reference a macro variable only?

Brian
Super Contributor
Super Contributor
Posts: 3,174

Re: %IF-%THEN-%ELSE behavior with %DO (iterative)

Normally, yes - do consider that SAS macro language code elements are executed at SAS program compilation time, unlike DATA step language elements which are executed with each DATA step iteration.

Scott Barry
SBBWorks, Inc.

Suggested Google advanced search argument, this topic / post:

macro language site:sas.com

macro read sas file sysfunc site:sas.com
SAS Super FREQ
Posts: 8,739

Re: %IF-%THEN-%ELSE behavior with %DO (iterative)

And, in addition to Scott's suggestions, this paper provides a good introduction to macro processing concepts and Step 9 shows how to use %IF to conditionally execute whole program steps or conditionally insert selected statements into compiled code:
http://www2.sas.com/proceedings/sugi28/056-28.pdf

cynthia
Regular Contributor
Posts: 241

Re: %IF-%THEN-%ELSE behavior with %DO (iterative)

I find it helpful separating out the iteration mechanism and the task that is to get done for each iteration.



   /* input data */


   data c1;


      a='a';


      b='b';


      c='';


      d='d';   


   run;


 


   /* macro to iterate */


   %macro doSomething(iter=);


      data c2;


         set c1;


         array letters(4) $ a b c d;


         x = &iter;


         var = strip(letters(x));


         if var='b' then put x= "true. var='b'";


         else put x= "false. var^='b'";


      run;


   %mend  doSomething;


 


   %*-- test running it one at a time --*;


   %doSomething(iter=1)


   %doSomething(iter=2)


 


   %*-- run them all --*;


   %macro doAll;


      %local i;


      %do i = 1 %to 4;


         %doSomething(iter=&i)


      %end;


   %mend  doAll;


   %doAll


   %*-- on log


   x=1 false. var^='b'


   x=2 true. var='b'


   x=3 false. var^='b'


   x=4 false. var^='b'


   --*;

Ask a Question
Discussion stats
  • 5 replies
  • 190 views
  • 0 likes
  • 4 in conversation