在 SAS 中的宏中嵌套宏调用

nesting a macro call within a macro in SAS

%outputter 是一个根据一组参数生成模拟结果的宏。这个宏的内容很详细并且妨碍了问题,但请注意宏包括多个 DATA 步和 PROC,并采用一些数字参数来实现它。例如:

%outputter(arg_a=4, arg_b=2, arg_c=0.01)

我需要 运行 宏数百次,每次迭代 arg_c 0.01。我通常使用围绕 PROC 或 DATA 步骤的宏进行迭代。例如:

%macro iterater(first=0.01, last=1.50);
%do i=&first. %to &last. %by 0.01;

/*<insert relevant code here>*/

%end;
%mend iterater;

%iterater

但在这种情况下,/*<insert relevant code here>*/的内容是%outputter。换句话说:

%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

如您所料,这中断了。我确定有一种解决方法涉及修改我的 %outputter 宏,但我想弄清楚如何将宏 %outputter 嵌套在宏 %iterator 中,以便 %outputter 运行s 150 次,每次使用 %iterator.

i 指定的 arg_c 参数的不同值

这个问题似乎与我读过的其他帖子不同,因为我的 %outputter 宏具有(并且出于用户功能目的的需要)用户定义的参数。

如果正确设置 DO 循环,您的代码实际上可以正常工作 - 我认为宏 BY 间隔需要整数。可能有一个解决方法,但不是那种突然想到的方法。其他人可以 post 该版本的解决方案。

%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=&param)

%put &param.;

%end;
%mend iterater;

%iterater

就我个人而言,我发现调试宏循环非常痛苦,因此我强烈建议改为使用 CALL EXECUTE 或 DOSUBL。我更喜欢单独生成字符串,这样我就可以将数据通过管道传输到数据集以确认创建正确。

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:修复了代码的引用问题(single/double 不匹配)。 EDIT2:添加 %NRSTR 以避免 运行 时间问题。我不知道这里需要它,但安全总比抱歉好。