SAS SQL 循环输入顺序文件

SAS SQL Loop Inputting Sequential Files

我有: 6个文件,命名如下:"ROSTER2008", "ROSTER2009", ..., "ROSTER2013" 每个文件都有这些变量:TEAMID 和 MATE1、MATE2、...、MATEX。为每个团队存储队友的名字,直到队友 X。

现在:我想遍历读取 6 个文件的代码并创建一个包含 TEAM、MATES2008、MATES2009、...、MATES2013 的输出文件,其中 MATES20XX 变量包含每个团队的队友数量那一年(我不再关心他们的名字)。

这是我尝试做的事情:

%macro sqlloop(start, end);
proc sql;
     %DO year=&start. %TO &end.;
         create table mates_by_team_&year. as 
         select distinct put(teamID, z2.) as team,
         count(*) as mates
         from myLibrary.rosters
         where d='ROSTER(HOW DO I PUT YEAR HERE?)'.d;
     %end;
quit;
%mend;

%sqlloop(start=2008, end=2013)

所以,这是我的问题:

  1. 如何修复 'where' 语句,使其能够理解我打算在每次迭代中引入的文件名? (即ROSTER2008,...,ROSTER2013)

  2. 现在,我正在为我输入的每个文件创建 6 个不同的 table。相反,我如何才能将这些文件合并为一个 table,正如我上面所描述的?

提前感谢您的帮助!

Xtina

假设这些是 SAS 数据集并且您使用的是 SAS 9.3+,我建议您使用数据步长和 proc freq 方法。它更容易理解。如果你想让它成为一个宏,用你的宏变量替换年份 (2008/2012)。

编辑:添加 N() 来计算队友的数量,假设它遵循 mate1 mate2 ... matex。 单个数据步会有答案,您可以删除变量。

Data combined;
Set roster2008 - roster2012 indsname=source;

 Year = substr(scan(source, 2, '.'), 7);

 Num_mates = n(of mate:); 

 *drop mate:;

 Run;

 PROC sort data=combined;
 By teamid year;
 Run;

 PROC transpose data=combined out=want prefix=mate;
 By teamid;
 VAR num_mates;
  Id year;
  Run;

  *OLD CODE BASED ON SQL SOLUTION;
 *Proc freq data=combined;
    *Table dsn*teamid/list;
  *Run;

为了简单起见,我假设你在 MATEX 中的 X 永远不会超过 999。显然你可以增加限制或您可以使用 proc contents 或字典表找出最大限制。

我把所有变量 Mate1:MateX 拉到一个数组中,检查它们是否丢失,并增加计数器来计算队友的数量。

%macro loops(start=,end=);

%do year=&start. %to &end.;
data year_&year.(keep=teamid Mates_&year.);
set roster&year.;
array mates{*} mate1-mate999;
Mates_&year.=0;
do i=1 to 999;
if not missing(mates{i}) then Mates_&year.=Mates_&year.+1;
end;
run;

proc sort data=year_&year.;
by teamid;
%end;

最后我将所有数据集合并在一起。

data team;
merge year_&start.-year_&end.;
by teamid;
run;

%mend;

%loops(start=2008,end=2009);