4797 11

SAS程序运行慢,求高手改进 [推广有奖]

  • 8关注
  • 2粉丝

讲师

33%

还不是VIP/贵宾

-

威望
0
论坛币
310 个
通用积分
0
学术水平
1 点
热心指数
1 点
信用等级
0 点
经验
15111 点
帖子
218
精华
0
在线时间
379 小时
注册时间
2012-10-31
最后登录
2020-8-31

楼主
慧(会)幸福 发表于 2013-4-2 10:54:54 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
下面的程序运行的超慢 ,各位高手能否帮我看看,是不是有可以改进的地方,在此多谢了。
libname DATA 'c:\SASDATA';
data data.ab;
a=-0.618;
b=1.618;
v=1+a*a;
u=1+(1-a)**2;
t=1+b*b;
s=1+(b-1)**2;
la=2*log(v/u);
lb=2*log(t/s);
c=la/log(1+a*a);
d=lb/log(1+b*b);
keep c d;
run;
options cmplib=sasuser.funcs;
proc fcmp outlib=sasuser.funcs.math  ;
  function lstar(u,c,d);
    if (u le  -0.618) then return (c*log(1+u*u));
    if (u ge  1.618) then  return (d*log(1+u*u));
else
      return(2*log((1+u*u)/(1+(u-1)*(u-1))));
endsub;run;
proc fcmp outlib=sasuser.funcs.statistics;
  function g(u);
    if (u le  -0.25) then return (2*log((1+0.25*0.25)/(1+1.25*1.25)));
    if (u ge  1.25) then  return (2*log((1+1.25*1.25)/(1+0.25*0.25)));
else
      return(2*log((1+u*u)/(1+(u-1)*(u-1))));
endsub;run;
proc printto log=_null_;
run;
options cmplib=sasuser.funcs;
%macro arim(r);
%do m=1 %to &r;
data data.lstar&m;
set ab;
do i=1 to 2000;
x=rand('T',3);
y=x/sqrt(3);
lstar=lstar(y,c,d);
l=g(y);
output;
end;
run;
data data.ci&m;
set data.lstar&m;
retain sum1 0;
sum1=sum1+lstar;
if (sum1 ge 0) then sum1=sum1;
else sum1=0;
output;keep i sum1;
run;
data data.si&m;
set data.lstar&m;
retain sum2 0;
sum2=sum2+l;
if (sum2 ge 0) then sum2=sum2;
else sum2=0;
output;keep i sum2;
run;
%end;
%mend arim;
%arim(10000);
proc printto log=_null_;
run;
libname data 'c:\SASDATA';
%macro ar(u);
%do n=1 %to &u;
%macro arim(r);
%do m=1 %to &r;
data shifts&m&n;
set data.ci&m;
if (sum1 ge (2.01+0.01*(&n-1))) then output;
run;
data shift&m&n;
set shifts&m&n;
if _n_=1 then output;keep i;
run;
data drifts&m&n;
set data.si&m;
if (sum2 ge (2.01+0.01*(&n-1))) then output;
run;
data drift&m&n;
set drifts&m&n;
if _n_=1 then output;keep i;
run;
%end;
%mend arim;
%arim(10000);
%macro test;
data sumshift&n;
set %do m=1 %to 10000;
shift&m&n
%end;
;
data sumdrift&n;
set %do m=1 %to 10000;
drift&m&n
%end;
;
%mend test;
%test;
%end;
%mend ar;
%ar(10);

%macro ar(u);
%do n=1 %to &u;
proc means data=sumshift&n;
var i;
output out=ci_shift&n(drop =_freq_ _type_)mean=ARL;
run;
proc means data=sumdrift&n;
var i;
output out=si_drift&n(drop =_freq_ _type_)mean=sARL;
run;
%end;
%mend ar;
%ar(10);
data ci_mean;
set ci_shift1-ci_shift10;
run;
data si_mean;
set si_drift1-si_drift10;
run;
data h;
do h=2.01 to 3 by 0.01;
output;end;
run;
libname SASDATA 'c:\SASDATA1';
data SASDATA.RLCUSUM6;
merge ci_mean si_mean h;
run;
proc gplot data=SASDATA.RLCUSUM6;
plot ARL*h=1 sARL*h=2/overlay;
symbol1 i=none v=dot;
symbol2 i=none v=dot c=black;
run;
proc gplot data=SASDATA.RLCUSUM6;
plot ARL*h=1 sARL*h=2;
symbol1 i=join v=none;
symbol2 i=join v=none;
run;
proc gplot data=SASDATA.RLCUSUM6;
plot ARL*h=1 sARL*h=2/overlay;
symbol1 i=join v=none;
symbol2 i=join v=none;
run;
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:sas程序 求高手 Statistics statistic function function return

已有 1 人评分学术水平 收起 理由
yukiooy + 1 你可不可以将这个程序的背景介绍一下?

总评分: 学术水平 + 1   查看全部评分

沙发
jingju11 发表于 2013-4-3 10:52:51
  1. libname DATA 'c:\SASDATA';
  2. proc printto log=_null_; run;

  3. data data.ab;
  4.   a=-0.618;
  5.   b=1.618;
  6.   v=1+a*a;
  7.   u=1+(1-a)**2;
  8.   t=1+b*b;
  9.   s=1+(b-1)**2;
  10.   la=2*log(v/u);
  11.   lb=2*log(t/s);
  12.   c=la/log(1+a*a);
  13.   d=lb/log(1+b*b);
  14.   keep c d;
  15. run;

  16. proc fcmp outlib=sasuser.funcs.math_stat;
  17.   # not clear to me how it works
  18.   function lstar(u,c,d);
  19.     if (u le  -0.618) then return (c*log(1+u*u));
  20.     if (u ge   1.618) then return (d*log(1+u*u));
  21.       else  return(2*log((1+u*u)/(1+(u-1)*(u-1))));
  22.   endsub;
  23.   function g(u);
  24.     if (u le  -0.25) then return (2*log((1+0.25*0.25)/(1+1.25*1.25)));
  25.     if (u ge   1.25) then return (2*log((1+1.25*1.25)/(1+0.25*0.25)));
  26.       else return(2*log((1+u*u)/(1+(u-1)*(u-1))));
  27.   endsub;
  28. run;

  29. options cmplib =sasuser.funcs;

  30. %let r =10000;
  31. data data.lstar;
  32.   call streaminit(1234); # for reproduce results
  33.   set ab;
  34.   do sample =1 to &r;
  35.     call missing(sum1, sum2);
  36.     do i =1 to 2000;
  37.       x     =rand('T',3)  ;
  38.       y     =x/sqrt(3)    ;
  39.       lstar =lstar(y,c,d) ;
  40.       l     =g(y)         ;
  41.       sum1 ++lstar; sum2 ++l;
  42.       if (sum1 lt 0) then sum1=0;
  43.       if (sum2 lt 0) then sum2=0;
  44.       output;
  45.     end;
  46.   end;
  47.   keep sample i sum1 sum2;
  48. run;

  49. data shifts_drifts;
  50.   set data.lstar;
  51.   by sample;
  52.   array _n[10] _temporary_ (1 2 3 4 5 6 7 8 9 10);
  53.   array _s[10] _temporary_;  array _d[10] _temporary_;
  54.   if first.sample then call missing(of _s[*] _d[*]);
  55.   do k =1 to dim(_n);
  56.     if _s[k] <1 then if (sum1 ge (2.01+0.01*(_n[k]-1))) then do;
  57.       _s[k] =1; n =_n[k]; cat ='shifts';
  58.       output shifts_drifts(keep =sample n i cat);
  59.     end;
  60.     if _d[k] <1 then if (sum2 ge (2.01+0.01*(_n[k]-1))) then do;
  61.       _d[k] =1; n =_n[k]; cat ='drifts';
  62.       output shifts_drifts(keep =sample n i cat);
  63.     end;
  64.   end;
  65. run;
  66.   
  67. proc means data=shifts_drifts;
  68.   class n cat;
  69.   var i;
  70.   output out=ci_shifts_drifts(drop =_freq_ _type_) mean=ARL_sARL;
  71. run;
复制代码
没有SAS无法测试。也可能没有完全理解你的程序(程序实在太长了)。我想小错误肯定有,自己修改。我的理解是,在模拟数据的时候,使用macro的效率几乎总是最差的。请注意:你的fcmp的逻辑不知道是否合理(是你想要的?)。
京剧

That is what I am doing:
1. Sampling and calculating lstar and l 2000 times;
2. Accumulating lstar and l to get sum1 and sum2 while adjusting them to 0 when their values are negative;
3. Using a threshold f(n), n =1, 2, 3, ... to fetch the first observation number where y >= f(n) was satisfied; when y =sum1, then called shifts, sum2 called drifts. Repeat n from 1 to 10, i.e. f(1), f(2), ...
4. Almost sure that each sample can return an qualified observation number since the sample size (=2000) is fairly large;
5. repeating above 1-4 10000 times (&r.), you may get 10000*10(=n) shifts and drifts each;
6. finding the shifts and drifts means for each n;
7. you will get 10 different (maybe) means for  each drifts and shifts;
8. plot the means for mean vs. h (from 2.00 to 2.09 by 0.01).
By the way, the FCMP may be right for you. I miss the return function at first time.
some typo in the code, such as to drop the keep= in separate output statement, etc.
And that what i got. Then run-tme is about 50s. Jingju
_1.PNG
已有 2 人评分经验 威望 论坛币 学术水平 热心指数 信用等级 收起 理由
admin + 2 对论坛有较大贡献,促进学术进步!
webgu + 100 + 100 + 5 + 5 + 5 这个得需要多大的热心和耐力啊。

总评分: 经验 + 100  威望 + 2  论坛币 + 100  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

藤椅
慧(会)幸福 发表于 2013-4-3 15:21:49
对于每一个n,我是想将ci1,... ...,ci10000中的那些大于或者等于2.01+0.01*(n-1)的那些sum1以及对应的i
存放到数据集shifts1n,... ...,shifts10000n,然后再分别输出输出shifts1n,... ... , shifts10000n中的第一个观测对应得i,将这些i 存放到shift1n,... ... ,shift10000n,再将这10000个数据集合并,并求i 得均值。我感觉我在这里搞得复杂了,程序应该就是慢在这里。


另外proc fcmp 应该没错

板凳
慧(会)幸福 发表于 2013-4-3 15:32:58
jingju11 发表于 2013-4-3 10:52
没有SAS无法测试。也可能没有完全理解你的程序(程序实在太长了)。我想小错误肯定有,自己修改。我的理解是 ...
54.data shifts_drifts;
55.  set data.lstar;

56.  by sample;

57.  array _n[10] _temporary_ (1 2 3 4 5 6 7 8 9 10);

58.  array _s[10] _temporary_;  array _d[10] _temporary_;

59.  if first.sample then call missing(of _s
  • _d
  • );

    60.  do k =1 to dim(_n);

    61.    if _s[k] <1 then if (sum1 ge (2.01+0.01*(_n[k]-1))) then do;
    62.      _s[k] =1; n =_n[k]; cat ='shifts';
    63.      output shifts_drifts(keep =sample n i cat);
    64.    end;

    65.    if _d[k] <1 then if (sum2 ge (2.01+0.01*(_n[k]-1))) then do;
    66.      _d[k] =1; n =_n[k]; cat ='drifts';

    67.      output shifts_drifts(keep =sample n i cat);
    68.    end;

    69.  end;
    70.run;




    这一段程序我看不懂,能否逐字逐句句帮忙解释下,的多谢您了,我是个菜鸟。另外call streaminit(1234); 括号里面的1234是随便选的吗,
    call missing(sum1, sum2);是什么意思
  • 报纸
    jingju11 发表于 2013-4-3 22:09:18
    And that what i got. Then run-tme is about 50s. Jingju

    _1.PNG

    地板
    webgu 发表于 2013-4-3 22:33:45
    call missing(sum1, sum2);是把 sum1,sum2置为缺失值。
    SAS资源
    1. SAS 微信:StatsThinking
    2. SAS QQ群:348941365

    7
    webgu 发表于 2013-4-3 22:35:42
    call missing(sum1, sum2);是将sum1,sum2置为缺失。
    SAS资源
    1. SAS 微信:StatsThinking
    2. SAS QQ群:348941365

    8
    慧(会)幸福 发表于 2013-4-4 09:11:06
    jingju11 发表于 2013-4-3 10:52
    没有SAS无法测试。也可能没有完全理解你的程序(程序实在太长了)。我想小错误肯定有,自己修改。我的理解是 ...
    太感谢您了!真的不知道还能再说出什么样的感谢的话来,再次感谢!

    9
    慧(会)幸福 发表于 2013-4-4 09:59:51
    webgu 发表于 2013-4-3 22:33
    call missing(sum1, sum2);是把 sum1,sum2置为缺失值。
    309    do k =1 to dim(_n);
    310
    311      if _s[k] <1 then if (sum1 ge (2.01+0.01*(_n[k]-1))) then do;
    312        _s[k] =1; n =_n[k]; cat ='shifts';
    313        output shifts_drifts(keep =sample n i cat);
                                   -
                                   22
                                   76
    ERROR 22-322: 语法错误,期望下列之一: 名称, 带引号的字符串, ;, RC, _DATA_, _LAST_, _NULL_.

    ERROR 76-322: 语法错误,语句将被忽略。

    314      end;
    上面的程序在SAS中运行后,出现以下结果,您能否帮忙查下,多谢您了!

    10
    慧(会)幸福 发表于 2013-4-4 11:34:50
    jingju11 发表于 2013-4-3 10:52
    没有SAS无法测试。也可能没有完全理解你的程序(程序实在太长了)。我想小错误肯定有,自己修改。我的理解是 ...
    这个图我用proc gplot没有画出来,求您指教。

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

    本版微信群
    加好友,备注cda
    拉您进交流群
    GMT+8, 2026-1-8 23:43