遵循此模式

我可以理解宏是在PDV创建之前就被解析的。但我真的想不出怎么从这段代码中。
data ds;
input id name $ value ;
datalines;
1 pluto 111
2 paperino 222
3 trump 333
4 topo 444
5 pippo 555
;
run;
%macro test(var) / mindelimiter=',';
if &var = "pippo"n then in0_&var. = name;
else out0_&var. = name;
%mend test;
data want;
set ds;
%test(pippo);
%test(arj);
%test(frank);
%test(pluto);
%test(george);
run;我得到了这个输出

CAn有人解释了这个过程的内在逻辑吗?
发布于 2016-05-19 11:52:46
就我理解您的注释而言,您期望的结果包含4列、id、name in和out,并且总是只有in或out才有值。
但是,对于每一行,都要调用5次宏。您应该只对每一行调用一次,然后就会得到预期的结果。
在这种情况下,您必须删除我在评论中声明的“at”&var,因为您在这里使用的是变量,而不是注释(更正了我的代码)。
数据步骤中的变量将被创建,即使它们是在一个if或else子句中,而这个子句永远不会被使用。因此,您为您调用宏的每个名称创建了一个in和一个输出变量,就像前面那样,为了避免这种情况,您可以使用宏if-否则,因为只有对数据步骤来说为true的子句才是可见的。例如:
%if "&var" = "pippo"n %then in0_&var = name;
%else out0_&var = name; 但是,如果变量var应该用作变量,则这是行不通的,因为您将得到in0_name而不是name的变量值,因为宏编译器不知道变量"name“的值。
此外,您还必须小心地使用宏变量,如果它应该用作数据步骤中的字符串,则必须使用"&var",否则它将被解释为变量。
宏使用宏值解析所有&-值,然后数据步骤解释该步骤。因此,在这种情况下,您不需要宏,只需在数据步骤中使用if-eg而不是宏调用,例如:
data want;
set ds;
if name = "pippo"n then in0 = name;
else out0 = name;
run;他们用你想要的方式,你应该用这个
%macro test(var) / mindelimiter=',';
if &var = "pippo"n then in0 = name;
else out0 = name;
%mend test;
data want;
set ds;
%test(name); /*This is called for every row in your dataset, so if you have 5 macrocalls,
they will be called 5 times for every row in your dataset*/
run;发布于 2016-05-20 11:24:05
如果您已经定义了宏,那么。
%macro test(var);
if &var = "pippo"n then in0_&var. = name;
else out0_&var. = name;
%mend test;并将参数var设置为值pippo调用它,它将生成代码:
if pippo = "pippo"n then in0_pippo = name;
else out0_pippo = name; 注意,这段代码将pippo的值与pippo的值进行比较(因为您使用的是名称字面)。永远都是这样。因此,它将始终将IN0_PIPPO设置为NAME的值,并且永远不会将任何值分配给OUT0_PIPPO。
如果您称它为var的其他值,例如FRANK,那么它将将该变量的值与PIPPO进行比较。
在调用此宏的示例数据步骤中,没有名为pippo或frank的变量,因此当引用它们时,SAS将创建缺少值的新变量。所以他们永远是平等的。所以所有的INO..。变量将被设置为NAME和所有OUT0的值.变量将被取消分配。
你发的照片显示,SAS完全按照你的要求做了。
https://stackoverflow.com/questions/37321659
复制相似问题