In a production environment, we often need to call a SAS macro multiple time and then pass many parameter values into the macro iteratively. For instance, we might have a dummy macro with only one parameter as below.
%macro silly(parm = ); %put ==> &parm; %mend silly;
There might be a situation that we need to call the above macro hundreds of times, each of which a different value should be passed to the macro parameter. For example, we might need to pass each element of 1000 values generated below into the above dummy macro.
data list; do i = 0 to 999; parm = "var"||put(i, z3.); output; end; run;
The most standard way to accomplish the aforementioned task is to parse each element one by one from a long string holding all values and then to loop through the macro 1,000 times as shown below. However, this approach is not only cumbersome to code but also computationally expensive.
*** method 1 ***; %macro loop; proc sql noprint; select parm into: parm separated by ' ' from list; quit; %let i = 1; %do %while (%scan(&parm, &i) ne %str()); %let var = %scan(&parm, &i); *** loop through each value on the list ***; %silly(parm = &var); %let i = %eval(&i + 1); %end; %mend loop; %loop;
A sleeker way is to take advantage of the internal iteration scheme in SAS data step and to call the macro iteratively by EXECUTE() routine, as demonstrated below. The code snippet is short and simple. More importantly, the run time of this new approach is approximately 4 – 5 times shorter than the run time used in a standard method.
*** method 2 ***; data _null_; set list; call execute('%silly(parm = '||parm||')'); run;