SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 920|回复: 6
打印 上一主题 下一主题

数组计算moving std问题

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2010-1-4 11:24:50 | 只看该作者

数组计算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
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2010-1-4 23:12:08 | 只看该作者

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。所以去掉它。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2010-1-5 15:46:28 | 只看该作者

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用。:(
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2010-1-5 22:37:08 | 只看该作者

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.
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2010-1-7 10:30:49 | 只看该作者

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的数吧?还是没法保证计算的是一个月内的。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2010-1-7 12:17:44 | 只看该作者

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]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2010-1-8 16:59:05 | 只看该作者

Re: 数组计算moving std问题

太赞了,原来SQL这么强大!!!我得好好学学了。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-2-6 09:44 , Processed in 0.078178 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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