在 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=¶m)
%put ¶m.;
%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 以避免 运行 时间问题。我不知道这里需要它,但安全总比抱歉好。
%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=¶m)
%put ¶m.;
%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 以避免 运行 时间问题。我不知道这里需要它,但安全总比抱歉好。