我有一个要运行几年的程序。因此,有时我必须选择我的数据
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&an”
您得出的答案(20&an
)是正确的-您已准备就绪。您甚至都不需要阅读我发布的其余答案:-)
但是我注意到您对&
vs有点困惑&&
。如果您想进一步了解,我整理了一些有关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
,我们只是使用普通的old &
,因此我们正在做以前的工作,读取并打印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
(即&&&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;
输出:
----- 3
----- 6
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句