SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

12
返回列表 发新帖
楼主: shiyiming
打印 上一主题 下一主题

一个有关SAS效率的问题

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
11#
 楼主| 发表于 2011-3-2 18:54:01 | 只看该作者

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

to jingju;

恩,我再试试这样的方法,之前试过发现最后ods 出来的是把第一个sample的结果append了很多次。。。不知道是不是哪里出现了问题

另外,SAS的快慢是不是与计算机的配置也有很大关系?
这是我昨天11点开始跑的一段程序,到现在(第二天晚上7点)了还没有跑完。。。我想就算把bootstrap那里改了改善会那么显著吗?不知道哪里还需调整

libname paper " D:\simulation2        ";
%macro boot;
   %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 x2;
                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 parameter estimate);
          set out_1;
          if StdErrRatio ne .;
          run;

        proc sort data=para;
           by parameter;
    run;

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

%mend;


%macro nonbootsurvival(n1,g,n,censor,var,label);
%do sn=1 %to 500;
        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);
                  x2=rand('BERNOULLI',0.5);
                  re=rand('normal',0,&var);
                  output;
                  end;
                run;

         data a4;
            merge a3 a2;

         run;

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

        proc phreg data=a5 covm covs;
            model t1*status(0)=z1 z2 x1 x2;
            id cluster;
                ods output parameterestimates=robustout;
        run;
  
        data robustout_&sn;
          set robustout;
          if StdErrRatio ne .;
        run;

    %if &sn>1 %then %do;
    proc datasets;
       append base=robustout_1
       data=robustout_&sn;
         quit;
        %end;
   
        **frailty model;
         ods output ParameterEstimates=est;
   proc nlmixed data=a5 noad;
       bounds gamma > 0;
       linp  = b1*(z1)+b2*(z2)+b3*(x1)+b4*(x2)+ z;
       alpha = exp(-linp);
       G_t   = exp(-(alpha*t1)**gamma);
       g     = gamma*alpha*((alpha*t1)**(gamma-1))*G_t;
       ll = (status=1)*log(g) + (status=0)*log(G_t);
       model t1 ~ general(ll);
       random z ~ normal(0,exp(2*logsig)) subject=id;  
   run;
     ods output close;

    data frailtout_&sn;
           set est;
          if parameter="logsig" then do;
      var=exp(2*estimate);
          tao=estimate/(2+estimate);
          end;
        run;

          %if &sn>1 %then %do;
    proc datasets;
       append base=frailtout_1
       data=frailtout_&sn;
         quit;
        %end;
          
                **original COX;

        proc phreg data=a5 covm covs;
            model t1*status(0)=z1 z2 x1 x2;
                ods output parameterestimates=coxout;
        run;
  
        data coxout_&sn;
          set coxout;
          if StdErrRatio ne .;
        run;

    %if &sn>1 %then %do;
    proc datasets;
       append base=coxout_1
       data=coxout_&sn;
         quit;
        %end;

        **bootstrap claculate sd;
  data temp ;set a5 ;keep id;run;

        %boot

  proc transpose data=temp3 out=sd_&sn._&label(drop=_LABEL_);
       id parameter;
       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;

  data robustci ;
  set robustout_1;
  IC_UP=estimate+1.96*StdErr;
  IC_low=estimate-1.96*StdErr;
  if parameter="z1" then true=-2;
  else if parameter="z2" then true=0.2;
  else if parameter="x1" then true=0.2;
  else if parameter="x2" then true=0.2;
  run;

  data paper.robust_&label;
    set robustci;
        if true>=IC_low and true<=IC_UP then cover=1;
        else cover=0;
    if ProbChiSq<0.05 then coverp=1;
        else coverp=0;
  run;

  data coxci ;
  set coxout_1;
  IC_UP=estimate+1.96*StdErr;
  IC_low=estimate-1.96*StdErr;
  if parameter="z1" then true=-2;
  else if parameter="z2" then true=0.2;
  else if parameter="x1" then true=0.2;
  else if parameter="x2" then true=0.2;
  run;

  data paper.cox_&label;
    set coxci;
        if true>=IC_low and true<=IC_UP then cover=1;
        else cover=0;
        if ProbChiSq<0.05 then coverp=1;
        else coverp=0;
  run;

  data frailtyci ;
  set frailtout_1;
  if parameter="b1" then true=2;
  else if parameter="b2" then true=-0.2;
  else if parameter="b3" then true=-0.2;
  else if parameter="b4" then true=-0.2;
  run;
  
  data paper.frailty_&label;
    set frailtyci;
        if true>=Lower and true<=upper then cover=1;
        else cover=0;
        if Probt<0.05 then coverp=1;
        else coverp=0;
  run;

%mend;

%nonbootsurvival(n1=10,g=50,n=500,censor=0.3,var=0.8,label=10_50_30_8);
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
12#
 楼主| 发表于 2011-3-2 18:57:01 | 只看该作者

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

to sxlion
哦///难道主要问题还是宏套宏?
在计算机上能有啥改进的余地不?比如把C盘剩余空间留大一点之类的,,,(我只是瞎猜测)
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
13#
 楼主| 发表于 2011-3-3 00:34:12 | 只看该作者

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

To jingju
忽略我上面的程序吧,我试了下,把%boot去掉了,果然快了很多!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

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

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

我有过这样的经验,简单说来是:如果用宏循环和数据步循环都可实现的情况,用数据步循环将更有效。
举个例子:
%macro one;
data one;
set rawdata;
%do i=1 %to 100;
select(var_&i);
%do j=1 %to 1000;
when(&&value_&j) ....;*此处省略具体操作;
%end;
otherwise;
end;
%end;
%mend;

%macro two;
data one;
set rawdata;
array v(100)  var_1-var_100;
drop i;
do i=1 to 100;
select(v(i));
%do j=1 %to 1000;
when(&&value_&j) ....;
%end;
otherwise;
end;
end;
%mend;


即使rawdata仅有不到100条数据,第一个宏编译的时间就要几倍于第二个,有时第一个宏干脆无法运行。如果用option Mprint, 我们会发现,第一个宏将生成一个大于100*1000行的程序,而第二个仅有约1000行。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
15#
 楼主| 发表于 2011-3-3 09:08:26 | 只看该作者

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

to caicaisas
最好是把%do sampnum=1 %to 500;%end这个宏循环改装到data步里。为proc phreg的by-processing创造条件。
如果这样的话,之后的proc append就是不必要的。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
16#
 楼主| 发表于 2011-3-3 13:00:14 | 只看该作者

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

to sun59338
是这样。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
17#
 楼主| 发表于 2011-3-3 19:00:19 | 只看该作者

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

我想问题的时候,最不希望用到宏。

不过有时为了省点代码时间和半自动化才用宏,但是也只挑一段地方。

用宏,也只用最简单的,最好不要用到什么条件,循环之类的宏,尽量少。

还有宏嵌套之类的,少碰啊,套来套去,debug困难,把自己套死了都不知道怎么死的。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-12 21:30 , Processed in 0.074348 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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