SAS中文论坛

标题: 数组计算moving std问题 [打印本页]

作者: shiyiming    时间: 2010-1-4 11:24
标题: 数组计算moving std问题
之前在这里请教过这个问题,大虾给出code如下:
[code:lzpr0xdh]
data stock;
        array a[0:179];
           ptr = -1;
           do _n_=1 by 1 until(last.permno);
      set stock;
      by permno;
      if _n_>180 then std = std(of a[*]);
      ptr = mod(ptr+1, 180);
      a[ptr] = ret;
      output;
   end;
   keep permno permco comnam date prc ret shrout std;
run;
[/code:lzpr0xdh]

在这里,数组数目是固定的180个,现在我想计算过去一个月的std,不过一个月中observations数可能不同,那么这里数组能变成浮动的么?

谢谢!还是不太会用数组  //blush
作者: shiyiming    时间: 2010-1-4 23:12
标题: Re: 数组计算moving std问题
Hi, 首先祝贺你:你的code很好啊!
如果仅仅是为了满足
[quote:1plngld6]。。计算过去一个月的std,不过一个月中observations数可能不同。。[/quote:1plngld6]
我想你的原始程序兼容这个问题。
我不知道怎么去定义一个维度浮动的数列。但我想先定义一个最大的,如果观测值少,数列就会把那些多余的变量设成是缺失值。反正std function 也不在乎缺失值。举个例子:
[code:1plngld6]data stock;
input permno ret@@;
cards;
1 3 1 7
2 6 2 5 2 7
3 9
4 .
;
data stock1(keep = permno std);
   array a(3);*3 is the maximum number of observations in one permno;
      do _n_= 1 by 1 until(last.permno);
         set stock;
         by permno;         
         a[_n_] = ret;
         if last.permno then std = std(of a[*]);  
      end;
      run;
proc print;run;[/code:1plngld6]
Sorry, 我想_TEMPORARY_在这里有些问题,因为它retain。所以去掉它。
作者: shiyiming    时间: 2010-1-5 15:46
标题: Re: 数组计算moving std问题
前面的code是别的大虾给的,呵呵。

不过我不知道最大是多少,因为我只要一个月之内的数据,一个月之内trading的次数是不一定的,有的可以非常多,有的可以非常少。如果设个大的数组,那么可能会包括到多于一个月的数据啊。

我自己的code还是用macro写的:
[code:2kf1l8pw]
data tempi5; run;

%macro movingstd;
%do i = 1 %to 359034;
%put &i;
data tempi;
        set originalfile;
        if _N_=&i;
run;

proc sql;
                create table tempi2 as
        select b.*
        from tempi a, originalfile b
        where a.name=b.name and b.date<a.date and b.date>=intnx('month', a.date, -1)
        order by date;
quit;

proc means data=tempi2 noprint;
        var cds;
        output out=tempi3(drop=_type_ _freq_) std=volatility;
run;

data tempi4;
        merge tempi tempi3;
run;

data tempi5;
        set tempi5 tempi4;
run;

%end;
%mend;
%movingstd;

run;
[/code:2kf1l8pw]

这个程序太不efficient了,用了20多个小时啊,大量时间用在不停地在硬盘上读写数据。后来我把temp的目录放在了内存上才快了一些些,但是也只用到CPU的一个核,我的CPU有8个核,其他的都没用到,不知道SAS里面怎么让它用多核CPU并行处理。

ps,我只有windows单机版,没有server用。:(
作者: shiyiming    时间: 2010-1-5 22:37
标题: Re: 数组计算moving std问题
[quote:2ekntwbj]不过我不知道最大是多少,因为我只要一个月之内的数据,一个月之内trading的次数是不一定的,有的可以非常多,有的可以非常少。如果设个大的数组,那么可能会包括到多于一个月的数据啊。[/quote:2ekntwbj]
[code:2ekntwbj]data _null_;
        retain yy 0;
        m = 0;
        do until(last.permno);
                set stock;                       
                by permno;
                m+1;
        end;
        if yy < m  then yy = m;
        call symput ('_dim', yy);
run;
%put &_dim
;[/code:2ekntwbj]
The above code gives you the dimension of the array used later on. You can define the array like
[code:2ekntwbj]array a(&_dim);[/code:2ekntwbj]
Again, I don't think the array will contain those values not belonged to.
作者: shiyiming    时间: 2010-1-7 10:30
标题: Re: 数组计算moving std问题
没大看懂...... <!-- s:? --><img src="{SMILIES_PATH}/icon_confused.gif" alt=":?" title="Confused" /><!-- s:? -->

我的数据还有一个date的变量
基本如下:
permno  date             ret
1           2002/01/01  0.1
1           2002/01/03  0.5
1           2002/02/03  0.2
1           2002/03/02  0.3
2 ...
2 ...
2 ...

也就是说,对于每一个permno,对应每一个date要求之前一个月内ret的std,即对于2002/02/03,求2002/01/03-2002/02/02之间的数据的std。

你的这个_dim倒是个好办法,不过现在最大值是一个permno里面的observations的数吧?还是没法保证计算的是一个月内的。
作者: shiyiming    时间: 2010-1-7 12:17
标题: Re: 数组计算moving std问题
看看是这意思不?
[code:1mxiazet]data raw;
        input permno date yymmdd10&#46; ret;
        format date yymmdd10&#46;;
datalines;
1 2002/01/01 0&#46;1
1 2002/01/02 0&#46;2
1 2002/01/03 0&#46;5
1 2002/02/01 0&#46;3
1 2002/02/02 0&#46;1
1 2002/02/03 0&#46;2
;

proc sql;
        create table temp(drop=startdate) as
                select *,(select std(ret)
                                                from raw b
                                                where b&#46;permno=a&#46;permno and
                                                        a&#46;startdate&lt;=b&#46;date&lt;a&#46;date
                                ) as std
                        from (select *,intnx('month',date,-1,'sameday') as startdate format yymmdd10&#46;
                                        from raw) a;
quit;[/code:1mxiazet]
作者: shiyiming    时间: 2010-1-8 16:59
标题: Re: 数组计算moving std问题
太赞了,原来SQL这么强大!!!我得好好学学了。




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2