Saturday, December 25, 2010

SAS中求列的和,一个简单例子的多个实现

options nodate nocenter  formdlim='8';
/* 这儿是原始数据,现在需要的是对summer1summer4求和,也就是说要得到36912  */
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;

/* 第二个办法,用macrosql混合使用 */
%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;

4 comments:

  1. 第三个办法,我刚开始用下面的办法算,一直不对。我也不明白为什么,哎

    %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;

    ReplyDelete
  2. 现在发现了,问题关键是:第二行,应该是maxobs,我写成maxbos,所以sas一直报错。ft了。要小心啊

    ReplyDelete
  3. 补充一个方法,用proc report
    proc 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