Hello
I was trying to learn about Macros in SAS. While reading the paper "Five Ways to Create Macro Variables: A Short Introduction to the Macro Language by Arthur L. Carpenter, I got stuck at the statement in the section on Iterative % DO loops page 4.
the %WHILE and %UNTIL specifications cannot be added to the increments
The author is an expert and there must be great significance in the above statement. I am unable to comprehend it.
Can anybody please help me understand this?
It is my understanding that %Do %WHILE and %DO %Until constructs can be used in macros.
Thanks in anticipation.
The SAS datastep allows for constructs as below.
data _null_;
do i=1 to 99 until(var>99);
var=i*i;
end;
put i= var=;
run;
The same is not possible with SAS macro language. Below code will return a syntax error.
%macro demo1();
%local var;
%do i=1 %to 99 %until(&var>99);
%let var= %eval(&i*&i);
%end;
%put &=i &=var;
%mend;
%demo1();
To express such logic on SAS macro level you need to implement differently - for example as below.
%macro demo2();
%local i;
%do %until(&var>99);
%let i=%eval(&i+1);
%let var= %eval(&i*&i);
%end;
%put &=i &=var;
%mend;
%demo2();
The SAS datastep allows for constructs as below.
data _null_;
do i=1 to 99 until(var>99);
var=i*i;
end;
put i= var=;
run;
The same is not possible with SAS macro language. Below code will return a syntax error.
%macro demo1();
%local var;
%do i=1 %to 99 %until(&var>99);
%let var= %eval(&i*&i);
%end;
%put &=i &=var;
%mend;
%demo1();
To express such logic on SAS macro level you need to implement differently - for example as below.
%macro demo2();
%local i;
%do %until(&var>99);
%let i=%eval(&i+1);
%let var= %eval(&i*&i);
%end;
%put &=i &=var;
%mend;
%demo2();
In normal SAS data step code, you could do something like this, which simultaneously uses both a do index range and an until condition as limits on the number of do loop iterations:
data _null_;
do i=1 to 90 until (rannum>0.9);
rannum=ranuni(4150913);
put i= rannum=;
end;
run;
The loop will stop once i is incremented beyond 90, or rannum exceeds 0.9, whichever happens first.
But if you write the intuitively analogous macro code, you get the error messages in the log below:
667 %macro t;
668 %do i=1 %to 90 %until (&rannum > 0.9);
669 %let rannum=%sysfunc(ranuni(4150913));
670 %end;
671 %mend t;
672 %t ;
ERROR: Improper use of macro reserved word until.
WARNING: Apparent symbolic reference RANNUM not resolved.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
operand is required. The condition was: 90 %until (&rannum > 0.9)
ERROR: The %TO value of the %DO I loop is invalid.
ERROR: The macro T will stop executing.
Instead, you have to include both the index limit and the until condition into a compound until condition:
%macro t;
%let i=0;
%do %until (&rannum > 0.9 OR &i=90);
%let i=%eval(&i+1);
%let rannum=%sysfunc(ranuni(4150913));
%put &=i &=rannum;
%end;
%mend t;
%t ;
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.