%outputter
is a macro that generates a simulated result based on a set of arguments. The contents of this macro are elaborate and get in the way of the question, but note that the macro includes multiple DATA step and PROCs, and takes some numeric arguments to get it going. For example:
%outputter(arg_a=4, arg_b=2, arg_c=0.01)
I need to run the macro hundreds of times, iterating arg_c
by 0.01 each time. I typically iterate with a macro wrapping around a PROC or DATA step. For example:
%macro iterater(first=0.01, last=1.50);
%do i=&first. %to &last. %by 0.01;
/*<insert relevant code here>*/
%end;
%mend iterater;
%iterater
But in this situation, the content of /*<insert relevant code here>*/
is the macro %outputter
. In other words:
%macro iterater(first=0.01, last=1.50);
%do i=&first. %to &last. %by 0.01;
%outputter(arg_a=4, arg_b=2, arg_c=&i)
%end;
%mend iterater;
%iterater
This breaks, as you'd expect. I'm sure there's a way around this that involves modifying my %outputter
macro, but I'd like to figure out how to nest the macro %outputter
within the macro %iterator
so that %outputter
runs 150 times, each time with a different value for the arg_c
argument that is specified by i
from %iterator
.
This question seems different from the other posts I have read through because my %outputter
macro has (and needs for user functionality purposes) user-defined arguments.
Your code will actually work fine, if the DO loop is set properly - I think macro BY
intervals requires whole numbers. There may be a workaround for that, but not that jumps to mind. Someone else can post that version of a solution.
%macro iterater(first=1, last=150);
%do i=&first. %to &last. ;
%let param = %sysevalf(&i/100);
%outputter(arg_a=4, arg_b=2, arg_c=¶m)
%put ¶m.;
%end;
%mend iterater;
%iterater
Personally, I find debugging macro loops a massive pain, so I highly recommend CALL EXECUTE or DOSUBL instead. I prefer to generate the string separately as then I can pipe the data to a data set to confirm things are created correctly.
data demo_call;
do i=0.01 to 1.5 by 0.01;
str = catt('%nrstr(%outputter(arg_a=4, arg_b = 2, arg_c=',
put(i, 8.2),
'));');
*once this is working, uncomment these lines to execute macro;
*output;
*call execute(str);
end;
run;
EDIT1: fixed quoting issue with code (single/double mismatch). EDIT2: added %NRSTR to avoid run time issues. I don't know that it's needed here but better safe than sorry.