SAS 宏流程说明

SAS MAcro flow explanation

遵循此架构

我可以理解宏在创建 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;

我得到这个输出

谁能解释一下这个过程的内在逻辑?

据我了解您的评论,您希望得到一个包含 4 列、id、name in 和 out 的结果,并且始终只有 in 或 out 有值。

但是你为每一行调用了 5 次宏。你应该只为每一行调用一次,然后你会得到预期的结果。

在那种情况下,你必须删除我在评论中提到的“at”&var“,因为你在这里使用的是变量,而不是评论(更正了我的代码)

数据步内的变量将被创建,即使它们位于永远不会被使用的 if 或 else 子句中。 因此,您按照以前的方式为调用宏的每个名称创建了一个 in 和一个 outvariable 为避免这种情况,您可以使用宏 if-else,因为只有为真的子句才会对数据步可见。例如:

%if "&var" = "pippo"n %then in0_&var = name;
%else out0_&var = name; 

但是如果 var 应该用作变量,这将不起作用,因为那样你会得到 in0_name 而不是 name 的变量值,因为变量 "name" 的值不是为宏编译器所知。

另外你必须小心如何使用宏变量,如果它应该在你的数据步骤中用作字符串,你必须使用“&var”,否则它会被解释为一个变量。

宏用宏值解析所有 &-值,之后数据步骤解释该步骤。 所以在这种情况下你不需要宏,你可以在数据步骤中使用 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;

如果您有定义的宏。

%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 进行比较。

在您调用此宏的示例数据步骤中,没有名为 pippofrank 的变量,因此当您引用它们时,SAS 将创建具有缺失值的新变量。所以他们永远是平等的。因此,所有 INO... 变量都将设置为 NAME 的值,并且所有 OUT0... 变量都将被取消分配。

您发布的图片表明 SAS 完全按照您的要求完成了工作。