循环遍历表并在 SAS 中加入它们

Looping through tables and joining them in SAS

我想不出解决一个问题。

我在一个 SAS 库中有未知数量的表。我想做一个循环,遍历它们和 "UNION ALL" 那些表。

表是预先检查过的,它们具有相同的结构。此表包含历史化数据,因此它应该是 Union all。 我尝试了以下脚本,但它会搜索所有可能性但不会执行 UNION ALL。

我很感激任何解决这个问题的想法。

%macro union_tables(table_name, last_extract); 
 %do i=1 %to &last_extract.;
        select * from data.&table_name&i
        union all
 %end;
        select * from data.&table_name&i
%mend;

proc sql; 
create table Full_history as 
%union_tables(Table_,1216);
quit;

提前谢谢你。

您的宏正在查找名为 table_1table_1216 的表,如果找不到不存在的表,则会向您报错。您需要更改循环,使其仅尝试获取实际存在的表的并集。

如果: A)所有文件名的总长度+它们的libname前缀+句点<32767;和 B)你的组成文件都在一个库中;和 C) 你的文件都以 'Table_'

开头
data _null_;
length datasets 767; *make sure this is long enough to hold all your dataset names + their libname prefix.  32767 is the max string length;
retain datasets;
set sashelp.vstable end=eof; *This system view holds all known datasets in all known libraries;
where upcase(libname)='DATA'; *The libname where you dsets live.  Use all uppercase;
if index(UPCASE(memname),'TABLE_') =1 /*Your code shows all datasets begin with 'Table_'*/ then
datasets=trim(datasets)||
 ' '||trim(libname)||
 '.'||trim(memname);
if eof then call symput('datasets',datasets);
run; 
%put &datasets; *print them to the log;

data all_the_datasets;
set &datasets;
run;

作为参考,我从 Richardson 和 Rossland 的 SUGI 29 论文的第 5 页抄录了大部分内容。

也许您可以放弃宏并使用 SET 语句。

data Many;
   set table_: open=defer;
   run;

如果表在变量方面完全相同并且类型 Open=defer 可以节省大量内存。

无论您的数据集如何命名,只需在创建顺序变量后将它们全部放入列表中并将它们放在一起(将 work. 替换为您的库命名的任何内容):

/* put all dataset names into a dataset */
proc contents data = work._all_ noprint out=ds_names(keep=memname); run;

/* dedupe the dataset and create an order variable */
data ds_names1; set ds_names;
    by memname;
    if first.memname;
    order_var + 1;
run;

/* put the ordered datasets into a macro variable list */
proc sql noprint;
    select distinct(memname)
    into: ds_list separated by " "
    from ds_names1
    order by order_var;
quit;

%put &ds_list.;

/* append all the datasets together in order */
%macro append_instead_of_set(ds_list);
%do i=1 %to %sysfunc(countw(&ds_list.));
    %let ds = %scan(&ds_list.,&i.);
    proc append data = &ds. base=full force; run;
%end;
%mend;

%append_instead_of_set(&ds_list.);

感谢大家的回复。我用了很少的东西来达到我需要的结果。

我想 post 我自己的结果,因为我使用了来自 Amw 5G 和 Foxer 用户的部分代码。

/* get list of the tables */ 

%MACRO SHOW_TABLES(libname, regex);
proc sql noprint;
select memname
into :list_tables separated by " "

from dictionary.tables
where libname="&libname." and upcase(memname) like upcase("%quote(%%)&&regex%")
order by memname;
quit;

%MEND;

%show_tables(DATA, Table_);

%put LIST OF TABLES: &list_tables.;

/* putting data sets together*/
DATA data.Full_history;
SET data.&list_tables.;
RUN;

这样它就把我所有的 table 放在一起,即使有一个不同的结构。因为 tables 可以随时间变化(可以删除某些列或添加新的列)。

对于proc append table应该有相同的结构。因此,就我而言,使用 data set .

是合理的