我可以理解宏甚至在创建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;
有人解释了这个过程的内在逻辑吗?
答案 0 :(得分:2)
据我所知,您希望结果包含4列,ID,名称输入和输出,并且始终只有输入或输出具有值。
但是你为每一行调用5次宏。你应该每行只调用一次,然后你就会得到预期的结果。
在这种情况下,您必须删除我在评论中说明的“at”& var“,因为您在此处使用变量,而不是注释(更正了我的代码)
即使数据块中的变量位于永远不会使用的if或else子句中,也会创建其中的变量。 因此,您以之前的方式为您调用宏的每个名称创建了一个in和outvariable 为避免这种情况,您可以使用宏if-else,因为只有datatesp才能看到true的子句。 e.G:
%if "&var" = "pippo"n %then in0_&var = name;
%else out0_&var = name;
但是如果var应该用作变量,那么这将不起作用,因为那样你将得到in0_name而不是name的变量值,因为macrocompiler不知道变量“name”的值。
另外你必须小心如何使用macrovariable,如果它应该在你的datastep中用作字符串,你必须使用“& var”,否则它将被解释为变量。
宏用宏值解析所有& -values,之后datasteps解释步骤。 所以在这种情况下你不需要宏,你可以在datastep中使用if-else而不是你的macrocall,例如:
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;
答案 1 :(得分:1)
如果你有一个定义它的宏。
%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完全按照您的要求行事。