SAS 宏循环聚合输出表
SAS macro loop aggregate output tables
我有一个定义如下的宏函数。
%macro sqlloop(event_id, empl_nbr_var, fleet, base, position);
...lots of code...
%mend;
这个宏创建了一个名为 export_table2
的 table,我想在我 运行 这段代码的所有时间里将其堆叠在一起。我在下面试过
data executed;
set work.vars;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2 summary_pilots;
run;
但这会出错,因为 summary_pilots 不存在,因为我正在尝试引用它。我还尝试了一个奇怪的工作,我将 vars
的第一行取出到新的 table 并将其从旧的删除,然后尝试执行下面的代码(其中 row1 是第一行,vars 是除了第一行之外的所有内容。
data _null_;
set Work.row1;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2;
run;
data executed;
set work.vars;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2 summary_pilots;
run;
但它仍然无法正常运行。这仅包括宏生成的第一个 table(来自第 1 行)和最后一个 table。我明白为什么会这样,因为调用 execute 是 运行 一次将它们全部连接起来并覆盖任何旧的 tables,但我仍然不知道如何修复它。任何将其放入早期数据步骤的尝试也都失败了。有什么建议吗?
首先,如果可能,要追加的代码需要放在 %sqlloop
中。如果没有,围绕 %sqlloop 创建一个包装宏,类似于
%macro write_loop(parameters...);
%sqlloop (parameters)
data summary_pilots... ;
run;
%mend write_loop;
然后call execute
那个。您还可以添加第二个 call execute
行,但这不必要地复杂。还有一些方法可以执行 %sqlloop
,这可能会为您提供单个数据集而不是行数据集,这在许多情况下最有可能是最好的。还有可能为每个 %sqlloop
执行提供一个唯一的数据集。对于单个数据集不起作用的大多数情况,我喜欢包含在宏中,但出于某些原因您可能更喜欢独特的数据集。
其次,根据细节,您有很多选项可以让整个事情发挥作用。 PROC APPEND
是一个好的开始,正如汤姆在评论中指出的那样;如果您要附加的数据集始终按列与之前的数据集相同,则该方法有效。
proc append base=summary_pilots data=export_table2;
quit;
这将在第一次 运行 时创建 summary_pilots
。这只有在列始终匹配的情况下才真正有效 - 听起来很可能? FORCE
选项也是可能的,但它对这类事情大多没有用,除非你保证第一个数据集是完整的变量数据集。
如果它们不匹配,那么您将得到 运行ning,然后再进行其他操作:
data summary_pilot;
stop;
run;
当然不要试图打开它 - 它不会打开,它没有行也没有列 - 但它存在,并且可以作为你的“基地”。如果你有一个好的“模板”,你也可以在其中定义列;我为一些项目这样做。
我有一个定义如下的宏函数。
%macro sqlloop(event_id, empl_nbr_var, fleet, base, position);
...lots of code...
%mend;
这个宏创建了一个名为 export_table2
的 table,我想在我 运行 这段代码的所有时间里将其堆叠在一起。我在下面试过
data executed;
set work.vars;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2 summary_pilots;
run;
但这会出错,因为 summary_pilots 不存在,因为我正在尝试引用它。我还尝试了一个奇怪的工作,我将 vars
的第一行取出到新的 table 并将其从旧的删除,然后尝试执行下面的代码(其中 row1 是第一行,vars 是除了第一行之外的所有内容。
data _null_;
set Work.row1;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2;
run;
data executed;
set work.vars;
call execute('%sqlloop(17,'||strip(empl_nbr_var)||','||strip(fleet)||','||strip(base)||','||strip(position)||');');
run;
data summary_pilots;
set work.export_table2 summary_pilots;
run;
但它仍然无法正常运行。这仅包括宏生成的第一个 table(来自第 1 行)和最后一个 table。我明白为什么会这样,因为调用 execute 是 运行 一次将它们全部连接起来并覆盖任何旧的 tables,但我仍然不知道如何修复它。任何将其放入早期数据步骤的尝试也都失败了。有什么建议吗?
首先,如果可能,要追加的代码需要放在 %sqlloop
中。如果没有,围绕 %sqlloop 创建一个包装宏,类似于
%macro write_loop(parameters...);
%sqlloop (parameters)
data summary_pilots... ;
run;
%mend write_loop;
然后call execute
那个。您还可以添加第二个 call execute
行,但这不必要地复杂。还有一些方法可以执行 %sqlloop
,这可能会为您提供单个数据集而不是行数据集,这在许多情况下最有可能是最好的。还有可能为每个 %sqlloop
执行提供一个唯一的数据集。对于单个数据集不起作用的大多数情况,我喜欢包含在宏中,但出于某些原因您可能更喜欢独特的数据集。
其次,根据细节,您有很多选项可以让整个事情发挥作用。 PROC APPEND
是一个好的开始,正如汤姆在评论中指出的那样;如果您要附加的数据集始终按列与之前的数据集相同,则该方法有效。
proc append base=summary_pilots data=export_table2;
quit;
这将在第一次 运行 时创建 summary_pilots
。这只有在列始终匹配的情况下才真正有效 - 听起来很可能? FORCE
选项也是可能的,但它对这类事情大多没有用,除非你保证第一个数据集是完整的变量数据集。
如果它们不匹配,那么您将得到 运行ning,然后再进行其他操作:
data summary_pilot;
stop;
run;
当然不要试图打开它 - 它不会打开,它没有行也没有列 - 但它存在,并且可以作为你的“基地”。如果你有一个好的“模板”,你也可以在其中定义列;我为一些项目这样做。