我有一个我想在几年内运行的程序。因此,有时我必须选择我的数据
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安培;一个”
答案 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_variable
是name_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;