繁体   English   中英

SAS调用宏变量

[英]SAS Call a macro variable

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

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的”

您得出的答案( 20&an )是正确的-您已准备就绪。 您甚至都不需要阅读我发布的其余答案:-)

但是我注意到您对& vs. &&有点困惑。 如果您想了解更多关于这一点,我放在一起上的区别一些额外的信息&&& ,以及目的&& ,在SAS宏观评估。

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

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

输出:

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

因此,您可以看到,必须在变量名称前加上& ,才能将其取消引用到其值。 省略&只是打印字符串an ,在这种情况下恰好是变量的名称。 对于大多数宏编码, &是您所需要的。 SAS宏中的&就像外壳中的$ ,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 &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.中的变量的值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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM