SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 1740|回复: 16
打印 上一主题 下一主题

一个有关SAS效率的问题

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2011-2-26 18:35:52 | 只看该作者

一个有关SAS效率的问题

Dear 版主及各位高手:
今天跑了一个自己写的宏,用了6小时,这还只是我模拟实验的几十分之一,如果按我的程序,估计真的很难毕业了,所以想请教下各位如何提高这段代码的效率?
不胜感激!!



%macro boot;                       /* bootstrap 重抽样后计算估计参数的STD*/
   %do sampnum=1 %to 500;
  data bootsamp_&sampnum;
            do i = 1 to nobs;                 
              x = round(ranuni(0) * nobs);   
              set temp  
                  nobs = nobs                     
                  point = x;              
              output;                     
           end;
         stop;                        
        run;

          proc sort data=bootsamp_&sampnum;
                              by id;
                run;

   data cox;
    merge bootsamp_&sampnum(in=b) a5(in=a);
        by id;
        if b;
  run;
   
        proc phreg data=cox covm covs;
            model t1*status(0)=z1 z2 x1 ;
                ods output parameterestimates=out_&sampnum;
        run;
  
         %if &sampnum>1 %then %do;
    proc datasets;
       append base=out_1
       data=out_&sampnum;
         quit;
         %end;
   %end;
   data para (keep=sampnum variable estimate);
          set out_1;
          if StdErrRatio ne .;
          run;

        proc sort data=para;
           by variable;
    run;

        proc means data=para std;
          var estimate;
          by variable;
          output out=temp2;
        run;
   data temp3;
     set temp2;
         if _STAT_="STD";
         keep Estimate variable;
   run;

%mend;



%macro caculatesd(n1,g,n,censor,label);     /*生成数据并将多次模拟的结果保存下来*/
%do sn=1 %to 100;
        data a1;
            do cluster=1 to &g;
                  z1=rand('BERNOULLI',0.5);
                  z2=rand('normal',2,1);
                  output;
                  end;
                run;

                data a2;
                  set  a1;
                  do i=1 to &n1;
                   output;
                  end;
                run;

                data a3;
                  do id=1 to &n;
                  u=rand('uniform');
                  lu=-log(u);
                  x1=rand('normal',3,1);
                  re=rand('normal',0,0.4);
                  output;
                  end;
                run;

         data a4;
            merge a3 a2;

         run;

         data a5;
           set a4;
                   t1=lu/exp(-2*z1+0.2*z2+0.2*x1+re);
           status=rand('BERNOULLI',&censor);
        run;

       data temp ;set a5 ;keep id;run;

        %boot                                                                  /*调用上一个宏程序*/

  proc transpose data=temp3 out=sd_&sn._&label(drop=_LABEL_);
       id variable;
       var estimate;          
   run;

   %if &sn>1 %then %do;
    proc datasets;
       append base=sd_1_&label
       data=sd_&sn._&label;
         quit;
         %end;
        %end;

        data paper.sd_&label;
           set sd_1_&label;
        run;
%mend;

%caculatesd(n1=10,g=50,n=500,censor=0.3,label=d10_50_30);


可以看到我的%caculatesd宏程序其实只做了100次,按道理来说至少要500次的,但是这个速度实在太可怕了,还望各位大侠出手相助!~
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2011-2-27 13:28:59 | 只看该作者

Re: 一个有关SAS效率的问题

没看你code的具体内容,但是在用SAS模拟的时候,确实是很费时间的,有的都是一直运行几天几夜才会有结果。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2011-3-1 00:42:14 | 只看该作者

Re: 一个有关SAS效率的问题

我仔细阅读了你的程序,自己做了些猜测,几点意见仅供参考:
1.我认为你的抽样方法还不是以cluster为单位的(如你以前的问题所提到的)。在程序里,random access那些ID而不是cluster;
2.如果不需要的东西就不要output出来。尤其是那个每次算500遍的phreg。这样会省很多的时间。也建议把一次calculation里的500 bootstrap samples整合到一个大的数据集里。利用proc phreg的by-processing减少phreg的开关次数。
如果得当,对于一般的PC,你的100次calcuations应该可以控制在15分钟之内。
JingJu
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2011-3-1 18:57:30 | 只看该作者

Re: 一个有关SAS效率的问题

就像jingju说的那样,如果不想要的data,就扼杀在摇篮中,不要把无用的data产生出来,然后又把人家忽略,这多浪费时间。

另外transpose之类的在数据多的时候就不要用的,尽量用data步来搞定。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2011-3-1 20:03:12 | 只看该作者

Re: 一个有关SAS效率的问题

to jingju11
呵呵,谢谢你的细心~~这个的确没有用cluster的bootstrap,因为模拟实验两个都要做的,所以只是放了最原始的bootstrap的程序~
另外至于 phreg里面的output 确实是有用的,可以看到每一次output的data我都存下了,最后用了append, 把他们合并成一个数据集,以方便最后算mean之类的,其实觉得append是个很不高效的做法,不过也没想出其他办法来
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2011-3-1 20:07:15 | 只看该作者

Re: 一个有关SAS效率的问题

哦,对了,这个程序其实是在100次里套了500次的bootstrap。。。。所以再×500,似乎也到了好几个小时了。。。。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2011-3-1 22:27:01 | 只看该作者

Re: 一个有关SAS效率的问题

如果再乘上100,岂不是比你原来的程序更慢?我怎么会害你,给你个更馊的主意呢?
你或许还没有理解我所说的output。如sxlion所言,你最后只是需要一个小小的数据集,为什么一定要把大篇大篇的结果listing出来呢?
另外,或许你没有抄完全,你的程序是无法运行的。不过即使这样,我也运行了一遍,如果100次caculations(你的100×500次phreg),的确大概15分钟。也就是说,如果是最后的500次,大概90分钟之内。
我还有一个观点或许不对,希望指正:
%boot为什么要做成macro,让它无聊地编译几百次呢?我总有一个观点,%macro nested %macro是个挺不高效的写法。尤其在此处,连个macro parameter都不需要的宏

[quote:3iu8g9ps]其实觉得append是个很不高效的做法[/quote:3iu8g9ps]
append的效率我也搞不清楚。不过我想,其本质是是否需要反反复复的使用这个过程。
京剧
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2011-3-1 23:43:13 | 只看该作者

Re: 一个有关SAS效率的问题

to jingju
恩,你说的非常对,我其实也没想过用%boot, 但是由于我想反复保存后面的phreg所出来的结果,所以只能用到out_&i的方式,如果要有&i 就必须把它包进宏里面。
我最先试过 data bootsamp;
   do sampnum = 1 to 1000;            
    do i = 1 to nobs;                 
      x = round(ranuni(0) * nobs);   
      set original   
          nobs = nobs                  
          point = x;              
      output;                     
   end;
end;
stop;                        
run;
这样的方式直接做bootstrap,但是去做proc phreg的时候就出现问题了。即使我用了 by sampnum; 按照每个sample来估计模型,但是最后却不能用 ods 将所有的结果都保存下来,这个我也很苦恼。。。。所以没有办法才做套了一个%boot
不知道您有没有好的办法?
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2011-3-2 00:27:39 | 只看该作者

Re: 一个有关SAS效率的问题

proc phreg data=cox covm covs;
[color=#BF0000:1mgyl193]by sampNum; [/color:1mgyl193]   [color=#0000FF:1mgyl193]***<------by-processing;[/color:1mgyl193]
model t1*status(0)=z1 z2 x1 ;
ods output parameterestimates=PhregOut;
run;
何必担心。如果加上by,那么每次的结果就自动append到输出数据phregOut里了。也就是说给出的phregout应是:
sampNum parameter estimate
1              z1             ***
1              z2            ***
1              x1             ***

2              z1             ***
2              z2            ***
2             x1             ***
.....
然后
proc means data =PhregOut nway;
class parameter;
output out =MeansOut std =std;
run;
很自然的,你的每一次boot其实就是给出3个记录的data set而已。
最后再用append吧每一次caculation的数据连接起来。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2011-3-2 18:41:19 | 只看该作者

Re: 一个有关SAS效率的问题

append的效率很高。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2025-6-11 11:14 , Processed in 0.071691 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表