楼主: wdxmahone
9605 26

[原创博文] sas数据提取 [推广有奖]

  • 0关注
  • 1粉丝

已卖:348份资源

硕士生

40%

还不是VIP/贵宾

-

威望
0
论坛币
12568 个
通用积分
0
学术水平
2 点
热心指数
3 点
信用等级
2 点
经验
3518 点
帖子
121
精华
0
在线时间
155 小时
注册时间
2010-1-11
最后登录
2022-9-4

楼主
wdxmahone 发表于 2010-1-28 09:46:49 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币
data a;
input stkcd $ date $ price mark;
cards;
00 2009-01-02 12.01 0
00 2009-01-03 12.03 0
00 2009-01-06 12.00 1
00 2009-01-07 11.56 0
00 2009-01-08 11.87 0

01 2009-01-02 10.01 0
01 2009-01-03 10.03 0
01 2009-01-06 10.00 0
01 2009-01-07 10.56 1
01 2009-01-08 10.87 0
;
run;

现在我想变成这样
stkcd            date        mark     a_1       a0        a1
  00         2009-01-06    1       12.03   12.00    11.56
  01         2009-01-07    1       10.00   10.56    10.87

就是将标记为1的观察值的前一个和后一个观察值的价格变量提取出来,写成上面的形式,重新定义新的变量。由于我要处理数据比较多,希望尽可能的用程序写出来,包括要提取的观察值也有几十个。
希望能够得到很好的解决,谢谢哈。。。。



我现在还有这种形式的数据:
data b;
input date& r00 r01;
cards;
2009-01-02 12.01 11.01
2009-01-03 12.03 11.03
2009-01-06 12.00 10.00
2009-01-07 11.56 10.56
2009-01-08 11.87 10.87

;
data d;
input stkcd $ date $ price;
cards;
r00 2009-01-06 12.00
r01 2009-01-07 10.56
;

run;

渴望能够得到正解。。。
二维码

扫码加我 拉你入群

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

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

关键词:数据提取 stkcd cards Input Price price

回帖推荐

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

粗粗测试了下,没有问题,通过设定before和after的值可以设置mark=1之前和之后的任意条记录,没有则为0 DATA步也可以做,代码有点难看,就用SQL啦......

zcxdxq 发表于2楼  查看完整内容

data a; input stkcd $ date $10. price mark; cards; 00 2009-01-02 12.01 0 00 2009-01-03 12.03 0 00 2009-01-06 12.00 1 00 2009-01-07 11.56 0 00 2009-01-08 11.87 0 01 2009-01-02 10.01 0 01 2009-01-03 10.03 0 01 2009-01-06 10.00 0 01 2009-01-07 10.56 1 01 2009-01-08 10.87 0 ; run; data b; set a; num+1; run; proc sql; create table d1 as select stkcd,price as a_1 from b ...

本帖被以下文库推荐

沙发
zcxdxq 发表于 2010-1-28 11:09:43
data a;
input stkcd $ date $10. price mark;
cards;
00 2009-01-02 12.01 0
00 2009-01-03 12.03 0
00 2009-01-06 12.00 1
00 2009-01-07 11.56 0
00 2009-01-08 11.87 0
01 2009-01-02 10.01 0
01 2009-01-03 10.03 0
01 2009-01-06 10.00 0
01 2009-01-07 10.56 1
01 2009-01-08 10.87 0
;
run;
data b;
        set a;
        num+1;
run;

proc sql;
        create table d1 as
                select stkcd,price as a_1 from b
                        where b.num in (select num-1 from b where b.mark = 1);
        create table d2 as
                select stkcd,date,price as a0,mark,num from b
                        where b.num in (select num from b where b.mark = 1);
        create table d3 as
                select stkcd,price as a1 from b
                        where b.num in (select num+1 from b where b.mark = 1);
        create table e as
                select d2.stkcd, d2.date, d2.mark, d1.a_1, d2.a0, d3.a1
                        from d1, d2, d3
                 where d1.stkcd = d2.stkcd and d2.stkcd = d3.stkcd;
已有 2 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
bakoll + 3 + 3 精彩帖子
wdxmahone + 1 + 1 + 1 相当有思想

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

藤椅
soporaeternus2 发表于 2010-1-28 11:35:45
  1. data a;
  2. input stkcd $ date:yymmdd10. price mark;
  3. format date yymmdd10.;
  4. cards;
  5. 00 2009-01-01 11.55 0
  6. 00 2009-01-02 12.01 0
  7. 00 2009-01-03 12.03 0
  8. 00 2009-01-06 12.00 1
  9. 00 2009-01-07 11.56 0
  10. 00 2009-01-08 11.87 0
  11. 01 2009-01-02 10.01 0
  12. 01 2009-01-03 10.03 0
  13. 01 2009-01-06 10.00 0
  14. 01 2009-01-07 10.56 1
  15. 01 2009-01-08 10.87 0
  16. 01 2009-01-09 11.11 0
  17. ;
  18. run;
  19. %MACRO MCR01(before,after);
  20. proc sort data=a;by stkcd date;run;quit;
  21. data a;
  22. set a;
  23. by stkcd date;
  24. if first.stkcd then i=0;
  25. i+1;
  26. run;
  27. data b;
  28. set a(where=(mark=1) keep=stkcd i mark rename=(i=i_0));
  29. drop mark;
  30. run;
  31. proc sql;
  32. create table c as
  33.   select
  34.     a.stkcd
  35.     ,sum(case when a.mark=1 then date
  36.     else 0
  37.     end) as date format=yymmdd10.
  38.     ,sum(case when a.mark=1 then 1
  39.     else 0
  40.     end) as mark
  41.     %do i_b=&before %to 1 %by -1;
  42.      ,sum(case when b.i_0-a.i=%eval(&i_b) then price
  43.      else 0
  44.      end) as a_&i_b
  45.     %end;
  46.      ,sum(case when a.i=b.i_0 then price
  47.      else 0
  48.      end) as a0
  49.     %do i_a=1 %to &after %by 1;
  50.      ,sum(case when a.i-b.i_0=%eval(&i_a) then price
  51.      else 0
  52.      end) as a&i_a
  53.     %end;
  54.   from a a
  55.   left join b b
  56.   on   a.stkcd=b.stkcd
  57.   group by a.stkcd
  58. ;      
  59. quit;
  60. %MEND MCR01;
  61. %MCR01(1,1);
  62. %MCR01(2,3);
  63. %MCR01(1,3);
复制代码

粗粗测试了下,没有问题,通过设定before和after的值可以设置mark=1之前和之后的任意条记录,没有则为0
DATA步也可以做,代码有点难看,就用SQL啦......
已有 2 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
bakoll + 3 + 3 精彩帖子
wdxmahone + 1 + 1 + 1 非常牛!

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

板凳
wdxmahone 发表于 2010-1-28 11:36:08
2# zcxdxq

很好,但是可能我的数据更复杂,每只股票多几个1就会出错(比如下面),不过这个应该可以处理,多提取几个变量匹配就行了。还有因为我可能要提取前后各五六十行,所以可能出现a_50, a50这些变量,可不可以通过循环来解决啊!

非常感谢。

data a;
input stkcd $ date $10. price mark;
cards;
00 2009-01-02 12.01 0
00 2009-01-03 12.03 1
00 2009-01-06 12.00 1
00 2009-01-07 11.56 0
00 2009-01-08 11.87 0
01 2009-01-02 10.01 0
01 2009-01-03 10.03 1
01 2009-01-06 10.00 0
01 2009-01-07 10.56 1
01 2009-01-08 10.87 0
;
run;

报纸
soporaeternus2 发表于 2010-1-28 11:44:12
LZ看我的3楼,可能可以满足你
但是一个stkcd 2个 mark=1 还不行
容我有时间修改下......

地板
wdxmahone 发表于 2010-1-28 11:55:09
3# soporaeternus2

不大能够看懂,我现在是边学习边使用,macro那一块内容,还没怎么看呢!还有,好像您习惯在程序编辑器里编辑,我一般在增强程序编辑器中编辑,您的那些代码,复制我的程序编辑器里不工作,而且我现在可能也没有能力去将您的程序修改用于我的工作,因为这一块我不太懂啊,最近在加紧学习呢!

不过还是谢谢了,二楼的sql语言还是比较通俗易懂的,现在主要是针对他提供的程序作修改了。

7
soporaeternus2 发表于 2010-1-28 12:13:27

  1. %MACRO MCR01(before,after);
  2. proc sort data=a;by stkcd date;run;quit;
  3. data a;
  4. set a;
  5. by stkcd date;
  6. if first.stkcd then i=0;
  7. i+1;
  8. run;
  9. data b;
  10. set a(where=(mark=1) keep=stkcd i mark rename=(i=i_0));
  11. drop mark;
  12. run;
  13. proc sql;
  14. create table c as
  15.   select
  16.     a.stkcd
  17.     ,sum(case when a.i=b.i_0 then date
  18.     else 0
  19.     end) as date format=yymmdd10.
  20.     ,sum(case when a.i=b.i_0 then 1
  21.     else 0
  22.     end) as mark
  23.     %do i_b=&before %to 1 %by -1;
  24.      ,sum(case when b.i_0-a.i=%eval(&i_b) then price
  25.      else 0
  26.      end) as a_&i_b
  27.     %end;
  28.      ,sum(case when a.i=b.i_0 then price
  29.      else 0
  30.      end) as a0
  31.     %do i_a=1 %to &after %by 1;
  32.      ,sum(case when a.i-b.i_0=%eval(&i_a) then price
  33.      else 0
  34.      end) as a&i_a
  35.     %end;
  36.   from a a
  37.   left join b b
  38.   on   a.stkcd=b.stkcd
  39.   group by a.stkcd
  40.      ,b.i_0
  41. ;      
  42. quit;
  43. %MEND MCR01;
  44. data a;
  45. input stkcd $ date:yymmdd10. price mark;
  46. format date yymmdd10.;
  47. cards;
  48. 00 2009-01-01 11.55 0
  49. 00 2009-01-02 12.01 0
  50. 00 2009-01-03 12.03 1
  51. 00 2009-01-06 12.00 1
  52. 00 2009-01-07 11.56 0
  53. 00 2009-01-08 11.87 0
  54. 01 2009-01-02 10.01 1
  55. 01 2009-01-03 10.03 1
  56. 01 2009-01-06 10.00 0
  57. 01 2009-01-07 10.56 1
  58. 01 2009-01-08 10.87 0
  59. 01 2009-01-09 11.11 0
  60. ;
  61. run;
  62. %MCR01(1,1);
  63. %MCR01(2,3);
  64. %MCR01(1,3);
复制代码

修改了下,一个stkcd多个mark=1貌似也可以了,没仔细测
楼主测试下......

8
yongyitian 发表于 2010-1-28 12:22:46
data b;
  set a;
   a_1 = lag(price);
   a0 = price;
   if lag(mark)= 1 then a_3 = price;
    else a_3 = 0;
run;

proc sql;
   create table c as
    select stkcd, date, price, mark, a_1, a0, sum(a_3) as a1
from b
group by stkcd
    order by stkcd, date;
quit;
data d;
   set c;
   where mark = 1;
run;

9
wdxmahone 发表于 2010-1-28 13:00:09
8# yongyitian

谢谢哈,这个如果是同一个Stkcd有两个以上的mark的话可能就会出错,而且只能滞后一项,我需要滞后好几十项呢,比如我要得到a_2,a_1,a0,a1,a2,这种做法不知道怎么样推广啊?

10
soporaeternus2 发表于 2010-1-28 13:05:09
看7楼,我改了下......

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-25 04:20