如何在更新宏变量并立即使用该值的数据步骤中调用宏?

时间:2017-02-03 19:47:40

标签: sas sas-macro

以下示例非常简单,可以更容易地解决。但是,我有兴趣让它发挥作用。以下示例基于sashelp-library的cars-dataset。首先,我有一个名为fun的宏:

proc contents data = sashelp.cars out = mycontents;
run;

%macro fun(var);
proc sql noprint;
        select count(distinct(&var.))
        into :obs
        from sashelp.cars;
quit;
%mend;

现在我想调用宏但只是为了更新obs(来自输入语句)。我用:

data work.test;
set mycontents;
if name ne "Type" then do;
      call execute('%nrstr(%fun('||name||');');
      new = &obs;
end;
else new = 5;

运行;

简而言之,这应该迭代mycontents的行。然后根据名称调用一个(多个)宏,更新obs。然后我可以简单地用obs填充新列new。但是,obs对所有名称保持相同的值,这是最后一个变量的值。

1 个答案:

答案 0 :(得分:6)

这里的问题是双重的。

首先,您不能在此上下文中使用CALL EXECUTE,因为在数据步骤完成运行之后不会执行:所以取决于&obs的任何内容都将无法获得更新的价值。您必须使用dosubl

其次,如果您想获得数据中间步骤的更新值,则需要使用symget('obs'),而不是&obs&obs将在编译数据步骤时解析,因此在执行期间不能更改;但是symget(obs)指示数据步骤在执行期间查询符号表。

以下是使用dosubl执行此操作的示例,与您的示例相比变化最小。请注意%global语句以确保我们在数据步骤中可以使用obs(还有其他方法可以将其更好地恢复 - 即将其包装在{{1}中函数和使用fcmp - 但这最接近你的工作方式。)

run_macro