楼主: mirandaling
5296 6

[问答] 如何用SAS补缺失数据 [推广有奖]

  • 0关注
  • 0粉丝

小学生

64%

还不是VIP/贵宾

-

威望
0
论坛币
1076 个
通用积分
0.0000
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
155 点
帖子
7
精华
0
在线时间
6 小时
注册时间
2010-3-16
最后登录
2023-3-2

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
我的数据是股票市值的半年数据,但是部分股票由于停牌等因素,在某段时间内没有数据,见举例:

Stock_code         Date                      Mon_Share
000004               2008-06-30            1000
000004               2008-12-31            1200
000004               2009-06-30            1400
000004               2010-06-30            1700
000004               2010-12-31            1600
000017               2006-06-30            1200
000017               2006-12-31            1300
000017               2010-06-30            4000

在例子中,000004缺2009-12-31的数据,000017缺2007-06-30一直到2009-12-31的数据,我现在想做的事情是把缺失数据补全,即如果该时点上面没有数,则显示该时间,市值等于上一个有数的值,比如说对于例子中的几个数,我希望得到这样的结果

Stock_code         Date                      Mon_Share
000004               2008-06-30            1000
000004               2008-12-31            1200
000004               2009-06-30            1400
000004               2009-12-31            1400
000004               2010-06-30            1700
000004               2010-12-31            1600
000017               2006-06-30            1200
000017               2006-12-31            1300
000017               2007-06-30            1300
000017               2007-12-31            1300
000017               2008-06-30            1300
000017               2008-12-31            1300
000017               2009-06-30            1300
000017               2009-12-31            1300

000017               2010-06-30            4000

试着用循环写了一下,觉得很复杂,求好心人士解答~~多谢!!!
二维码

扫码加我 拉你入群

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

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

关键词:缺失数据 如何用 share Stock tock 如何

回帖推荐

geniusv 发表于5楼  查看完整内容

不好意思,刚才睡觉的时候想了一个很简单的,赶紧重新开机回复下,以上那段代码就无视吧。用下面这段程序,不解释,非常好懂。 data x; input a b : yymmdd10. c; format b yymmdd10.; cards; 000004 2008-06-30 1000 000004 2008-12-31 1200 000004 2009-06-30 1400 000004 2010-06-30 1700 000004 ...

geniusv 发表于3楼  查看完整内容

说实话我也不知道有没有比较简单又好理解的方法,我提供一个不算非常好但是比较好理解的方法吧:用index。 简单起见就假设你那三个变量名字叫做a b c。先读入数据 data x; input a b : yymmdd10. c; format b yymmdd10.; cards; 000004 2008-06-30 1000 000004 2008-12-31 1200 000004 2009-06-30 1400 000004 2010-06-30 ...
沙发
hhtpku 发表于 2013-3-19 23:20:41 |只看作者 |坛友微信交流群
要不试试proc expand.

使用道具

藤椅
geniusv 发表于 2013-3-20 00:14:16 |只看作者 |坛友微信交流群
说实话我也不知道有没有比较简单又好理解的方法,我提供一个不算非常好但是比较好理解的方法吧:用index。
简单起见就假设你那三个变量名字叫做a b c。先读入数据
data x;
input a b : yymmdd10. c;
format b yymmdd10.;
cards;
000004               2008-06-30            1000
000004               2008-12-31            1200
000004               2009-06-30            1400
000004               2010-06-30            1700
000004               2010-12-31            1600
000017               2006-06-30            1200
000017               2006-12-31            1300
000017               2010-06-30            4000
;
run;
虽然你数据排好序了,但是真实数据可能你还是需要排序一下。排序后输出到y,顺便创建个index叫做ab
proc sort data=x out=y(index=(ab=(a b)));by a b;run;
然后创建一个没有c变量的数据集,使b变量遍历同一个a值得最小b值到最大b值(如果是半年一次数据的话)输出到数据集z
proc sql;
create table range as
select a,min(b) as min format=yymmdd10., max(b) as max format=yymmdd10.
from x
group by 1;
quit;

data z;
set range;
format b yymmdd10.;
b=min;
do while(b<=max);
output;
b=intnx('month',b,6,'e');
end;
drop min max;
run;
最后用index把c变量带进来,如果找不到ab中对应的索引值,会自动把最近的c值复制下来的。
data final;
set z;
set y key=ab;
if _iorc_ ne 0 then _error_=0;
run;
上面if语句其实可以不加,但是由于index找不到相应值会在log里面把_error_加1,所以如果想把log弄好看点可以加上这个if语句(其实不加结果也一样,哈哈)

以上使我想到的比较好理解但是也不算简单的方法。
如果把中间缺的日期用上一个日期覆盖,再match merge 一下也可以达到同样的效果。不过也不算太简单的方法。

使用道具

板凳
mirandaling 发表于 2013-3-20 00:33:05 |只看作者 |坛友微信交流群
geniusv 发表于 2013-3-20 00:14
说实话我也不知道有没有比较简单又好理解的方法,我提供一个不算非常好但是比较好理解的方法吧:用index。
...
确实不算简单。。。不过看起来似乎也是个办法,我去试一下,谢谢~~

使用道具

报纸
geniusv 发表于 2013-3-20 01:02:07 |只看作者 |坛友微信交流群
不好意思,刚才睡觉的时候想了一个很简单的,赶紧重新开机回复下,以上那段代码就无视吧。用下面这段程序,不解释,非常好懂。
data x;
input a b : yymmdd10. c;
format b yymmdd10.;
cards;
000004               2008-06-30            1000
000004               2008-12-31            1200
000004               2009-06-30            1400
000004               2010-06-30            1700
000004               2010-12-31            1600
000017               2006-06-30            1200
000017               2006-12-31            1300
000017               2010-06-30            4000
;
run;

proc sort data=x;by a descending b;
run;

data y(rename=(b1=b));
        retain b1;
        format b1 yymmdd10.;
        set x;
        by a;
        if first.a then
                do;
                b1=b;
                output;
                end;
        else
                do while (b1>b);
                b1=intnx('month',b1,-6,'e');
                output;
                end;
        drop b;
proc print data=y;run;

使用道具

地板
mirandaling 发表于 2013-3-20 10:25:13 |只看作者 |坛友微信交流群
geniusv 发表于 2013-3-20 01:02
不好意思,刚才睡觉的时候想了一个很简单的,赶紧重新开机回复下,以上那段代码就无视吧。用下面这段程序, ...
啊,非常明白,十分感谢!!

使用道具

7
hhtpku 发表于 2013-3-20 11:14:18 |只看作者 |坛友微信交流群
啊,赞一个!

使用道具

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

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-24 04:31