options nodate nocenter formdlim='8';
/* 这儿是原始数据,现在需要的是对summer1到summer4求和,也就是说要得到3,6,9,12 */
data wide;
input name $ summer1-summer4;
cards;
a 1 2 3 4
b 1 2 3 4
c 1 2 3 4
;
/* 第一种办法,用矩阵来做,因为涉及到对同一个变量反复做相同的操作 */
data sum_array;
set wide end=last;
array summer{4} summer1-summer4;
array asum{4};
keep asum1-asum4;
do i=1 to 4;
asum{i}+summer{i};
end;
if last then output;
run;
proc print data=sum_array noobs;
run;
/* 第二个办法,用macro和sql混合使用 */
%MACRO sumver(maxindex=);
%DO n = 1 %TO &maxindex;
SUM(summer&n) as Sum&n
%IF &n NE &maxindex %THEN ,
;
%END;
%MEND sumver;
PROC SQL;
SELECT %sumver(maxindex=4)
FROM wide
;
QUIT;
/* 第三个办法,用macro来代替反复执行 */
%macro Test(Countt);
data sum_data;
set wide end=lastobs;
%do i =1 %to &Countt;
sum&i+summer&i;
%end;
keep sum1-sum&Countt;
if lastobs then output;
run;
%mend;
%Test(4);
proc print data=sum_data;
run;
/* 第四个办法,用一段macro来代替执行所有的相加项 */
%macro sumv(maxobs=);
%do i=1 %to &maxobs;
sum&i+summer&i ;
%end;
%mend sumv;
option mlogic mprint symbolGEN;
data sum_data;
set wide end=lastobs;
%sumv(maxobs=4) ;
keep sum1-sum4;
if lastobs then output;
run;
第三个办法,我刚开始用下面的办法算,一直不对。我也不明白为什么,哎
ReplyDelete%macro sumv(maxobs=);
%do i=1 %to &maxbos;
asum&i+summer&i
%if &i ne &maxobs %then ;
;
%end;
%mend;
data sum_data;
set wide end=lastobs;
%sumv(maxobs=4);
keep sum1-sum4;
if lastobs then output;
run;
现在发现了,问题关键是:第二行,应该是maxobs,我写成maxbos,所以sas一直报错。ft了。要小心啊
ReplyDelete补充一个方法,用proc report
ReplyDeleteproc report data=wide nowd;
column summer1 summer2 summer3 summer4;
define summer1/sum "sum1";
define summer2/sum "sum2";
define summer3/sum "sum3";
define summer4/sum "sum4";
run;
谢谢!!
ReplyDelete