SAS调用宏变量

时间:2014-10-08 09:53:04

标签: variables macros sas

我有一个我想在几年内运行的程序。因此,有时我必须选择我的数据

data want;
    set have(where='2014');
    run;

要试用几年,我有一个宏变量,我定义为

%let an=14
/*It is 14 and not 2014, because elsewhere I need it that way.*/

但是当我尝试将它放入我的程序时它根本不起作用

data want;
    set have(where="&&20&an.");
    run;

我很感激一些帮助

首先编辑:将''更改为“”,但仍无法正常工作

第二次修改和回答

“20安培;一个”

1 个答案:

答案 0 :(得分:3)

你到达的答案(20&an)是正确的 - 你已经准备好了。您甚至不需要阅读我发布的其余答案: - )

但是我注意到你对&&&有点混淆。如果您想了解更多相关信息,我会在SAS宏评估中汇总一些关于&&&之间差异的额外信息,以及&&的目的。

&是最常见的符号 - 您只需使用它来评估/取消引用变量。所以:

%LET an = 14 ;
%PUT ----- an ;
%PUT ----- &an ;

输出:

----- an
----- 14

正如您所看到的,您必须在变量名之前加上&,以便将其取消引用到其值。省略&只会打印字符串an,在这种情况下恰好是变量的名称。对于大多数宏编码,&就是您所需要的。 SAS宏中的&类似于shell中的$,C中的*等等。


现在,&&是什么?它的存在使您可以拥有动态宏变量名称。也就是说,有一个宏变量,其值是另一个宏变量的名称。如果您熟悉C,可以将其视为指向指针的指针。

SAS评估&&的方式分为两次。在第一轮中,它会将&&转换为&。同时,它在该过程中看到的任何&符号将用于取消引用它们旁边的变量名称。这个想法是为了后面这些表达式解析为变量名称。然后,在第二遍中,剩余的&符号(所有原始&&个符号)取消引用它们现在找到的任何变量名称。

以下是示例输出的示例:

%LET x = 3;
%LET name_of_variable = x;

%PUT ----- &x;
%PUT ----- &&name_of_variable;
%PUT ----- &&&name_of_variable;

输出:

----- 3
----- x
----- 3

在第一个%PUT中,我们只使用普通的&,因此我们正在做我们之前所做的事情,阅读并打印x所持有的值。在第二个%PUT中,事情会变得更有趣。由于&&,SAS会进行两次评估。第一个转换为:

%PUT ----- &&name_of_variable;

到此

%PUT ----- &name_of_variable;

在第二轮中,SAS执行标准&评估以打印name_of_variable中保存的值 - 字符串x,这恰好是我们所在的另一个变量的名称使用。当然,这个例子特别做作:为什么你写&&name_of_variable时会写&name_of_variable

在我们现在拥有%PUT的第三个&&&中,SAS执行两次传递。这是我们最终看到&&的真正目的的地方。我将表达式的部分放在括号中,以便您可以看到它们的评估方式。我们从这里开始:

%PUT ----- (&&)(&name_of_variable);

对此:

%PUT ----- &x;

因此,在第一遍中,&&已转换为&,而&name_of_variablename_of_variable的简单解除引用,正在评估其内容持有,正如我们所说的x

所以在第二遍中,我们只剩下简单的评估:

%PUT ----- &x;

由于我们将x设置为等于3,因此评估为3。

从某种意义上说,&&&name_of_variable说“向我显示名称存储在name_of_variable.中的变量的值”

这是一个激励性的例子,说明你为什么要这样做。假设您有一个简单的宏子例程,它将一个任意数字添加到存储在SAS宏变量中的数值。要做到这一点,子程序必须知道要添加的数量,但更重要的是,它需要知道要添加的变量的名称。您将通过&&机制完成此动态变量命名,如下所示:

%MACRO increment_by_amount (var_name = , amount = );
    %LET &var_name = %EVAL (&&&var_name + &amount) ;
    /* Note: this could also begin with %LET &&var_name = .... */
%MEND;

我们在这里说:“让名称保存在var_name中的变量(即&var_name)等于名称保存在var_name中的变量的值(即{{ 1}})加上&&&var_name中保存的值(即amount)。

当你调用这样的子程序时,请确保传递变量名称,而不是值。就是这样说:

&amount

不是这个:

%increment_by_amount (var_name = x , amount = 3 );

所以调用的例子是:

%increment_by_amount (var_name = &x , amount = 3);

输出:

%LET x = 3;
%PUT ----- &x;
%increment_by_amount (var_name = x , amount = 3 );
%PUT ----- &x;