我来试试:
%macro processyear(Inputds,Year,Outputds);
proc sql;
create table &Outputds as /*创建数据集,名为&outputds*/
select /*选择变量年份、编号、分数、平均分数*/
Year
,StudentID
,Score
,Avg(Score) as YearAvg
from &Inputds /*指定输入数据集&inputds*/
where year=&year /*只选择年份为&year的数据*/
group by
Year /*按照年份分组*/
order by
Score desc /*将结果数据集按分数的降序排列*/
;
quit;
data &Outputds;
set &Outputds;
by descending Score; /*按分数降序读入数据*/
if _N_=1; /*选择第一条记录,即分数最高的记录*/
rename StudentID=StudentHighScore; /*更改变量名*/
drop Score;
run;
%mend processyear;
%processyear(StudentScore,95,Year_Out);
%MACRO split;
proc sort data=StudentScore;by StudentId year;run;quit; /*将数据集按编号、年份排序*/
data t1;
set StudentScore;
by StudentId year; /*按编号、年份顺序依次读入数据*/
Grp=compress(StudentID||'_'||year); /*生成Grp变量,值为编号与年份组合,如A_91*/
if first.year; /*选择每个编号+年份组合的第一条记录,目的是对每个编号和年份组合只记录一次*/
keep StudentID year Grp; /*保存需要的变量*/
run;
proc sql;
select Grp into:output separated by '|' from t1; /*将所有编号+年份的组合保存在宏变量output中,并以字符'|'分隔*/
quit;
%let cnt=%eval(%sysfunc(count(&output,|))+1); /*数出编号+年份组合的个数,保存在宏变量cnt中*/
%put &output &cnt; /*在log中输出宏变量output和cnt的值*/
data
%do i=1 %to &cnt;
%scan(&output,&i,|)
%end;
; /*在Data语句中列出所有的编号+年份组合。data A_91 A_92 B_91 ...;*/
set StudentScore;
/*以下Do循环将每个编号和年份的数据输出到对应的数据集中。*/
%do i=1 %to &cnt;
%if &i>=2 %then %do;else%end;
if StudentID="%scan(%scan(&output,&i,|),1,_)" and year=%scan(%scan(&output,&i,|),2,_) then output %scan(&output,&i,|);
%end;
;
run;
%MEND split;
%SPLIT;