楼主: addictedtome
5544 24

[原创博文] SAS求解一个问题,关于寻找连续出现的变量 [推广有奖]

11
soporaeternus 发表于 2010-4-20 09:07:16
10# yatming
contains '1111'
这个办法不错,学习了
Let them be hard, but never unjust

12
crackman 发表于 2010-4-20 09:14:47

学习了
谢谢10楼的兄弟

13
addictedtome 发表于 2010-4-20 11:17:24
谢谢10楼的朋友,你对数据的解释很准确。

但是我刚刚开始学SAS,所以你的程序很多我看不懂。。。

我觉得版主的程序更简单一些...

14
yatming 发表于 2010-4-20 13:19:38
13# addictedtome
呵呵,如果猜想没错的话,7楼那个max(date)-min(date)>=365的限制就会有些问题了。
举个例子吧:
对于某个fund,持有某个stock的时间点只有两个:2004-03-31,2005-12-31
可以看到对于这个group,max(date)-min(date)虽然大于等于365,但从明细时间点看并不是连续四个月持有。
貌似好像也没有什么汇总函数能在此条件上再进行限制来达到所要的结果。

代码可以慢慢理解,我的想法是构造一个变量来表现历史持有的记录。所以构造了hsy变量,先计算min(date),然后通过每个observation中date与min(date)的季度差,来对历史持有记录进行更新,使用0,1来标识。最后,要连续四个月持有,则只要历史记录中含有‘1111’的字符串就可以了。

当然这只是我的想法,希望有机会能看到更好的方法来实现。

15
sushe1527 发表于 2010-4-20 15:39:10
编辑中、。。。

16
sushe1527 发表于 2010-4-20 15:49:08
是不是这个意思,建立一个新变量 mark=dif(year(date)*4+qtr(date))
使得它在某类stock下连续出现3个1即可?

data raw;
input stock$ date : yymmdd10. code;
format date yymmdd10.;
cards;
001 2000-03-30 14
001 2005-03-30 15
001 2005-06-30 15
001 2005-06-30 15
001 2005-09-30 15
001 2005-12-30 15
001 2010-6-30  15
001 2050-6-30  90
001 2050-7-30  90
002 2005-06-30 20
002 2005-09-30 20
002 2005-12-30 20
002 2006-01-30 20
002 2012-01-30 88
003 2006-01-30 88
003 2012-01-30 88
;run;
proc sort data=raw out=b
dupout=dupdata nodupkey;
by  stock date code;
run;
proc sort data=b;by stock date ;run;
data tmp;
set b;
by stock date ;
mark=dif(year(date)*4+qtr(date));
if mark=1 then z+mark;
else z=0;
if z=3 then output;
run;
proc sql;create table tmp1 as
select * from raw as left join tmp
on raw.stock=tmp.stock and raw.code=tmp.code;quit;
data final; merge raw tmp1;by stock date code;
if mark=. then mark=0;drop z;run;
已有 3 人评分经验 学术水平 热心指数 信用等级 收起 理由
addictedtome + 1 + 1 + 1 非常感谢
crackman + 100 + 1 不错
soporaeternus + 1 *4 很强大

总评分: 经验 + 100  学术水平 + 3  热心指数 + 1  信用等级 + 1   查看全部评分

17
yatming 发表于 2010-4-20 16:56:36
楼上的dif方法很有意思,学习了。。。
而且采用数值计算,极端情况效率上会好很多。

18
soporaeternus 发表于 2010-4-20 17:02:29
16楼的那个乘以4很妙啊.....
Let them be hard, but never unjust

19
crackman 发表于 2010-4-20 17:22:19
看了这么多高手来写这个程序来讨论确实收获很多
不过首先我得澄清我对数据集的认识可能和大家不一样

我以为DATE是每一天的值 而不是每一个季度的值

所以在写程序的时候,我是计算了一个基金 持有某一个股票,持有的日期中最近时间和最远时间的差值,同时对观察对象的每一天进行标记,如果差值大于365天,那么标记为1,如果差值为365,但是实际上没有365天,例如只有两天的时候,刚好差值为366,但是只有两天啊,所以我加了一个标记变量等于差值,同时差值大于365,那么就输出得到结果数据集,我是这样理解的

yatming兄弟提出几个错误之处,我很感谢,第一个就是sql 里面的sum(n)=dif这个是有问题,substr字符分切函数来说,确实第三个参数是字长,但是如果按照我那样写,也可以得出结果,可能是一个巧合吧

后面的程序我觉得大家写的很不错
前提是对数据集的理解存在偏差

20
yatming 发表于 2010-4-20 17:31:37
恩,如果是有每天数据,楼上的sum(n)=dif来判断连续也是很不错的方法。
16楼那个乘以4的原因确实很有意外的收获,呵呵。

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

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