【问题标题】:SAS Call a macro variableSAS 调用宏变量
【发布时间】:2014-12-02 22:37:13
【问题描述】:

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

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”。部分。
  • 感谢您的提示,它适用于“20&an”。但如果不能与“&&20&an”一起使用。我很高兴它有效,但如果你知道为什么另一个没有,我会很乐意解释
  • 和号主要用于解析宏变量。对于 20&an,&an 解析为 14,因此当与 20 结合时,您将得到 2014。&&20&an 变为 &2014,但没有宏变量 2014,这就是 &&20&an 不起作用的原因。
  • "&&20&an."仅当存在宏变量“&20”时才有效。由于这只是硬编码,因此您只需要“20&an”。
  • 谢谢,我想我必须将 20&an 声明为宏变量。

标签: variables macros sas


【解决方案1】:

您得到的答案 (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 的简单取消引用,评估它所持有的内容,正如我们所说的@ 987654367@.

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

%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)。

当您调用这样的子例程时,请确保您传递的是变量 name,而不是值。也就是说,这样说:

%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

【讨论】:

  • 我明天会在睡一觉后阅读它(对我来说是一天的结束),但非常感谢!
  • 随时。我听说你睡着了!
  • 非常清晰和有启发性的谢谢。我很高兴我的标题如此含糊,它可能会让其他人找到你明确而有用的答案!
  • 很高兴为您提供帮助。这个 SAS 宏的东西可能非常晦涩,但一旦弄清楚就很强大。同意该标题将帮助其他人找到它。谢谢采纳!
  • 注意:对最后的激励示例部分进行了微小的修改......宏体最初盯着%LET &&var_name =,这在技术上是正确的,但说%LET &var_name = 真的更清楚。我也在更改旁边发表了评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多