【发布时间】:2016-10-05 00:17:34
【问题描述】:
我有理由使用重复过程来处理给定数据集的不同变量。为了解决这个问题,我编写了一个宏,它的输入是感兴趣的特定变量。然后宏将只处理该变量。然而,事实证明需要对其中一个变量进行稍微不同的处理。我的快速解决方法是应用条件;如果变量是异常,则执行与其他变量不同的操作。问题解决了,对吧?没有。
我发现宏变量的值会根据它是否在数据步骤中使用而变化。
请考虑,
data example;
length dataset_var1 $ 6 dataset_var2 $ 6;
input dataset_var1 $ dataset_var2;
datalines;
value1 value2
value3 value4
;
run;
宏及其调用:
%macro NoQuotes(macro_var);
%put ¯o_var. ;
data _null;
set example;
put ¯o_var. ;
if ¯o_var. = 'dataset_var1' then do;
put "The IF evaluated";
end;
else do;
put "The ELSE evaluated";
end;
run;
%put ¯o_var. ;
%mend;
%NoQuotes(dataset_var1);
这会产生以下日志条目:
dataset_var1
value1
The ELSE evaluated
value3
The ELSE evaluated
NOTE: There were 2 observations read from the data set WORK.EXAMPLE.
NOTE: The data set WORK._NULL has 2 observations and 2 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
dataset_var1
注意macro_var 的值如何根据它是否在 DATA 步内而变化。在 DATA 步中,macro_var 采用dataset_var1 的值,即value1 和value3,而不是像您期望的那样保留名称dataset_var1。一旦超出 DATA 步,macro_var 的值就会神奇地返回到正确的值。
根据同事的建议,我在条件语句中将宏变量的名称放在引号中。这使得条件的行为符合预期。
%macro WithQuotes(macro_var);
%put ¯o_var. ;
data _null_;
set example;
put ¯o_var. ;
if "¯o_var." = 'dataset_var1' then do;
put "The IF evaluated";
end;
else do;
put "The ELSE evaluated";
end;
run;
%put ¯o_var. ;
%mend;
%WithQuotes(dataset_var1);
这会产生以下日志条目:
dataset_var1
value1
The IF evaluated
value3
The IF evaluated
NOTE: There were 2 observations read from the data set WORK.EXAMPLE.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
dataset_var1
虽然条件现在按预期执行,但我们再次看到宏变量采用value1 和value3 的值。
宏变量的行为似乎与我所知道的关于 BASIC、C++、Java、C#、VBA、Python、Lisp 和 R 中的变量概念的一切背道而驰。
有人可以向我解释发生了什么吗?我已经阅读了大部分Macro Language Reference,但不确定在哪里可以找到这种行为的解释。
【问题讨论】: