使用SAS,我经常想对数据集的每一行执行操作。为此,我使用了在教程中找到的命令:call execute()
。由于我对SAS环境不太熟悉,我倾向于使用宏功能来做任何我不知道如何使用call execute()
执行它们的事情。
但是我很难理解宏语言在SAS中是如何工作的。我知道所有的宏引用都先被解析,这提供了一个base-SAS代码然后被执行(或者我已经错了?)。但我不明白它如何应用call execute()
。
我们来考虑以下代码:
%macro prog1; /* %prog1 defines a macrovariable mv1 */
%global mv1;
data _null_;
call symputx("mv1","plop");
run;
%mend;
%macro prog2(var); /* prog2 puts it on the log */
%put PUT &var;
%mend;
%macro prog_glob; /* prog_glob executes prog 1 then prog2 */
%prog1;
%prog2(&mv1);
%mend;
我知道这里不需要三个宏,但这是我的真实代码的最小版本,它具有这种结构。
现在,如果我执行prog_glob
:
%prog_glob;
我按预期在日志上获得PUT plop
。
但是如果我将它与call execute()
一起使用(即使这里不需要循环):
data _null_;
mac=%NRSTR("%prog_glob");
call execute(mac);
run;
我只获得PUT
。
没有错误表明未定义macrovariable,因此%global
语句有效。但不知何故,prog2
在prog1
基础部分之前执行(至少我认为是这样)并且mv1
尚未定义。
我的问题是:
call execute
?编辑:我的原始代码打算重命名我在数据集中列出的几个表的变量。对于每个列出的表,我希望执行以下算法:
mv
等效的地方)可能有一种更聪明的方法可以做到这一点。我再也不熟悉SAS,而且我倾向于过度使用宏。如果你想告诉我一个更好的方法,我很乐意聊天,但我不希望你们重写我的所有代码,所以替代call execute
就足够了我要感激不尽! :)
答案 0 :(得分:2)
让我们看看文档 http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000543697.htm
如果EXECUTE例程参数是宏调用或解析为1,则宏立即执行。但是, EXECUTE例程生成的任何SAS语句在步骤边界传递之后才会执行。
注意:由于宏引用会立即执行,并且SAS语句在步骤边界之后才会执行,因此不能使用CALL EXECUTE来调用包含由该宏中的CALL SYMPUT创建的宏变量的引用的宏。有关示例,请参阅与宏工具的接口。
这意味着,如果您通过调用execute:
调用它立即执行宏语句 - 这些是:
1.1。首先在%prog1:%global mv1; - 所以定义了mv1但是空,没有明显的...警告
1.2。来自%prog1的SAS语句仍然是延期
现在正在执行从调用执行延迟的SAS语句:
4.1。 prog1的数据集设置mv1的值。
这就是全部: - )
编辑:关于您的修改:尝试查看此http://support.sas.com/kb/48/674.html
答案 1 :(得分:0)
data _null_;
mac='%nrstr(%prog_glob)';
call execute(mac);
run;
or, more plainly, as you would see in the documentation...
data _null_;
call execute('%nrstr(%prog_glob)');
run;
or
%let prog=%nrstr(%prog_glob);
data _null_;
mac="&prog.";
call execute(mac);
run;
or, and I wouldn't really recommend this one, but you could also manually concatenate the macro quotes
data _null_;
mac=cats('01'x,'%prog_glob','02'x);
call execute(mac);
run;
The way you are running it, the macro statements get execute at run time and the data step is execute after the calling data step completes. You're not properly using %NRSTR for this context, as described by the documentation. You need to pass the macro, along with the quoting as text to the call routine.