【发布时间】:2014-12-09 09:57:22
【问题描述】:
使用 SAS,我经常想对数据集的每一行执行一个操作。为此,我使用了在教程中找到的命令:call execute()。由于我对 SAS 环境不是很熟悉,所以我倾向于使用宏函数来做任何我不知道如何执行的事情,并使用call execute() 执行它们。
但是,我很难理解宏语言在 SAS 中是如何工作的。我知道首先解析所有宏引用,它提供了一个基本 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。
没有错误提示未定义宏变量,因此 %global 语句有效。但不知何故,prog2 是在prog1 基础部分之前执行的(至少我是这么认为的),而mv1 尚未定义。
我的问题是:
- 我的解释正确吗?
- 为什么我使用
call execute时结果会改变? - 根据前面的问题答案,我应该如何修复它或者是否有更方便的方法来循环遍历列值?
编辑: 我的原始代码打算重命名几个表的变量,这些表我已在数据集中列出。对于每个列出的表,我希望执行以下算法:
- prog1 : 在宏变量中存储一个包含所有变量的列表(这是我定义
mv等效项的地方) - prog2 : 为这些变量名称添加通用后缀
可能有更聪明的方法来做到这一点。同样,我对 SAS 不太熟悉,而且我倾向于过度使用宏。如果你想告诉我一个更好的方法来做到这一点,我很乐意聊天,但我不希望你们重写我所有的代码,所以call execute 的替代品足以让我感激不尽! :)
【问题讨论】:
-
这是一个关于如何重命名变量stackoverflow.com/questions/26855371/…的上一个问题的链接