gpt4 book ai didi

sas - 宏变量在 DATA 步中具有不同的值。为什么?

转载 作者:行者123 更新时间:2023-12-04 13:46:28 28 4
gpt4 key购买 nike

我有理由使用重复过程处理给定数据集的不同变量。为了解决这个问题,我写了一个宏,它的输入是感兴趣的特定变量。然后宏将仅处理该变量。然而,事实证明,需要稍微不同地处理其中一个变量。我的快速解决方法是应用条件;如果变量是异常(exception),则执行与其他变量不同的操作。问题解决了对吧?不。

我发现宏变量的值会根据是否在数据步骤中使用而发生变化。

请考虑,

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 &macro_var. ;

data _null;
set example;

put &macro_var. ;

if &macro_var. = 'dataset_var1' then do;
put "The IF evaluated";
end;
else do;
put "The ELSE evaluated";
end;
run;

%put &macro_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 ,即 value1value3 ,而不是保留名称 dataset_var1正如你所期望的那样。一旦超出 DATA 步,值 macro_var神奇地恢复到正确的值。

根据同事的建议,我将宏变量的名称放在条件语句中的引号中。这使得条件行为符合预期。
%macro WithQuotes(macro_var);
%put &macro_var. ;

data _null_;
set example;

put &macro_var. ;

if "&macro_var." = 'dataset_var1' then do;
put "The IF evaluated";
end;
else do;
put "The ELSE evaluated";
end;
run;

%put &macro_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 ,但不确定在哪里可以找到这种行为的解释。

最佳答案

简短的回答:
尝试使用宏 %IF 语句而不是数据步骤语言 IF 语句。

长答案:
宏语言是一种预处理器,它处理文本以生成代码。一般来说,宏语言不知道SAS数据集或数据集中的变量。 DATA 步语言处理数据集和数据集变量。宏语言看起来和DATA步语言很相似,但它们的用途完全不同,是两种不同的语言。

考虑:

87   options mprint;
88
89 %macro ShowValue(var);
90 data _null_;
91 set sashelp.class (obs=3);
92
93 %put The macro variable VAR has the value: &VAR;
94 put "The dataset variable &VAR has the value: " &VAR;
95
96 run;
97
98 %mend;
99
100 %ShowValue(var=height)
MPRINT(SHOWVALUE): data _null_;
MPRINT(SHOWVALUE): set sashelp.class (obs=3);
The macro variable VAR has the value: height
MPRINT(SHOWVALUE): put "The dataset variable height has the value: " height;
MPRINT(SHOWVALUE): run;

The dataset variable height has the value: 69
The dataset variable height has the value: 56.5
The dataset variable height has the value: 65.3
NOTE: There were 3 observations read from the data set SASHELP.CLASS.

宏语言有一个 %PUT 语句,数据步语言有一个 PUT 语句。上面,%PUT 语句的目的是显示名为 VAR 的宏变量(参数)的值.用户向它传递了一个值 height .上面 PUT 语句的目的是显示用户命名的数据步骤变量的值。因为用户传递了值 height ,列出该数据集变量的值(对于处理的所有三个记录)。名为 VAR 的宏变量始终具有值 height .名为 height 的数据集变量不同的记录有不同的值。请注意 %PUT 语句只执行一次,即使认为它在数据步骤循环内。这是因为宏语句是在执行(甚至编译)任何数据步骤代码之前执行的。 PUT 语句是数据步骤代码,因此它为数据步骤处理的每条记录编译和执行一次。 PUT 语句需要引用,以便它可以将文本文字与数据步骤变量的名称区分开来。 %PUT 语句(实际上是整个宏语言)不需要引号,因为宏变量由 & 引用。

如果要根据宏变量的值进行条件评估以决定宏应生成哪个数据步骤,可以使用宏 %IF 语句,例如:
102  %macro ShowValue(var);
103 data _null_;
104 set sashelp.class (obs=3);
105
106 %if &var=height %then %do;
107 &var=&var * 2.54; *convert height from inches to cm;
108 %end;
109
110 %put The macro variable VAR has the value: &VAR;
111 put "The dataset variable &VAR has the value: " &VAR;
112
113 run;
114
115 %mend;
116
117 %ShowValue(var=height)
MPRINT(SHOWVALUE): data _null_;
MPRINT(SHOWVALUE): set sashelp.class (obs=3);
MPRINT(SHOWVALUE): height=height * 2.54;
MPRINT(SHOWVALUE): *convert height from inches to cm;
The macro variable VAR has the value: height
MPRINT(SHOWVALUE): put "The dataset variable height has the value: " height;
MPRINT(SHOWVALUE): run;

The dataset variable height has the value: 175.26
The dataset variable height has the value: 143.51
The dataset variable height has the value: 165.862
NOTE: There were 3 observations read from the data set SASHELP.CLASS.

118 %ShowValue(var=weight)
MPRINT(SHOWVALUE): data _null_;
MPRINT(SHOWVALUE): set sashelp.class (obs=3);
The macro variable VAR has the value: weight
MPRINT(SHOWVALUE): put "The dataset variable weight has the value: " weight;
MPRINT(SHOWVALUE): run;

The dataset variable weight has the value: 112.5
The dataset variable weight has the value: 84
The dataset variable weight has the value: 98
NOTE: There were 3 observations read from the data set SASHELP.CLASS.

宏 %IF 语句解析宏变量并将该宏变量的解析值与文本字符串 height 进行比较。 .请注意,%IF 语句中不需要(或想要)引号。因为宏语言是用于文本处理的,所以它不使用引号来表示文本值。

简而言之,使用宏%IF语句根据宏变量中存储的文本值进行决策来控制宏语言生成哪个数据步代码,使用数据步IF语句根据数据值进行决策步骤变量来控制执行哪个数据步骤代码。 (IF 语句中引用的数据步变量的名称可以通过使用宏变量甚至宏生成。)

了解 %PUT 与 PUT、%IF 与 IF、%DO 与 DO 等之间的区别是学习使用宏语言的关键步骤。

关于sas - 宏变量在 DATA 步中具有不同的值。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39842975/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com