楼主: wdxmahone
9607 26

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

11
wdxmahone 发表于 2010-1-28 13:19:17
10# soporaeternus2

7楼我看不太懂啊,再研究研究。。。

12
yongyitian 发表于 2010-1-28 13:45:27
把你想要的 Stkcd有两个以上的mark的 结果贴出来

13
wdxmahone 发表于 2010-1-28 14:05:46
12# yongyitian 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;
现在我想变成这样
stkcd            date        mark     a_2     a_1       a0        a1        a2
  00         2009-01-03    1          .       12.01   12.03    12.00     11.56
  00         2009-01-06    1       12.01   12.03   12.00    11.56     11.87
  01         2009-01-03    1           .      10.01   10.03    10.00     10.56
  01         2009-01-07    1       10.03   10.00   10.56    10.87        .

您帮忙再给看一下,谢谢哈!

14
soporaeternus2 发表于 2010-1-28 14:06:42
正好有空,写了点注释,实在不擅长写......
  1. %MACRO MCR01(before,after);
  2. /*before:mark=1记录前需要转置的记录数*/
  3. /*after:mark=1记录后需要转置的记录数*/
  4. /*每个stkcd下每条记录按date唯一顺序标记*/
  5. proc sort data=a;by stkcd date;run;quit;
  6. data a;
  7.         set a;
  8.         by stkcd date;
  9.         if first.stkcd then i=0;
  10.         i+1;
  11. run;
  12. /*需要输出的date 以及它们的标记*/
  13. data b;
  14.         set a(where=(mark=1) keep=stkcd i mark rename=(i=i_0));
  15.         drop mark;
  16. run;

  17. proc sql;
  18.         create table c as
  19.                 select
  20. .stkcd
  21. /*date输出*/
  22. ,sum(case when a.i=b.i_0 then date
  23.       else 0
  24.       end) as date format=yymmdd10.
  25.       /*mark输出*/
  26.       ,sum(case when a.i=b.i_0 then 1
  27.       else 0
  28.       end) as mark
  29.       /*mark=1前 第&before 条记录 转置为 变量 a_&before*/
  30.       %do i_b=&before %to 1 %by -1;
  31.               ,sum(case when b.i_0-a.i=%eval(&i_b) then price
  32.               else 0
  33.               end) as a_&i_b
  34.       %end;
  35.       /*a0记录*/
  36.               ,sum(case when a.i=b.i_0 then price
  37.               else 0
  38.               end) as a0
  39.       /*mark=1后 第&after 条记录 转置为 变量 a&after*/
  40.       %do i_a=1 %to &after %by 1;
  41.               ,sum(case when a.i-b.i_0=%eval(&i_a) then price
  42.               else 0
  43.               end) as a&i_a
  44.       %end;
  45.                 from        a a
  46.                 left join        b b
  47.                 on                        a.stkcd=b.stkcd
  48.                 group by        a.stkcd
  49.                                         ,b.i_0
  50.         ;                                                        
  51. quit;
  52. %MEND MCR01;
  53. data a;
  54. input stkcd $ date:yymmdd10. price mark;
  55. format date yymmdd10.;
  56. cards;
  57. 00 2009-01-01 11.55 0
  58. 00 2009-01-02 12.01 0
  59. 00 2009-01-03 12.03 1
  60. 00 2009-01-06 12.00 1
  61. 00 2009-01-07 11.56 0
  62. 00 2009-01-08 11.87 0
  63. 01 2009-01-02 10.01 1
  64. 01 2009-01-03 10.03 1
  65. 01 2009-01-06 10.00 0
  66. 01 2009-01-07 10.56 1
  67. 01 2009-01-08 10.87 0
  68. 01 2009-01-09 11.11 0
  69. ;
  70. run;
  71. %MCR01(1,1);
  72. %MCR01(2,3);
  73. %MCR01(1,3);
复制代码

对于我以上的测试数据
在before=2 after=3下
即运行%MCR01(2,3);
则输出
stkcd        date        mark        a_2        a_1        a0        a1        a2        a3
0        2009-1-3        1        11.55        12.01        12.03        12        11.56        11.87
0        2009-1-6        1        12.01        12.03        12        11.56        11.87        0
1        2009-1-2        1        0        0        10.01        10.03        10        10.56
1        2009-1-3        1        0        10.01        10.03        10        10.56        10.87
1        2009-1-7        1        10.03        10        10.56        10.87        11.11        0

15
lpxuan 发表于 2010-1-28 19:46:08
顶。。。。。。。。。。。。

16
bobguy 发表于 2010-1-29 06:42:29
wdxmahone 发表于 2010-1-28 09:46
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;

渴望能够得到正解。。。
Here is a simpler solution.

data a;
input stkcd $ date yymmdd10. price mark;
format date yymmdd10.;
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;
  by stkcd;  
  a_1=lag2(price);
  a0=lag1(price);
  mark1=lag1(mark);
  if first.stkcd then do;
     a_1=.; a0=.;mark1=.;
  end;
  if mark1=1 then output;
  rename  price=a1 mark1=mark;
  drop mark;
run;

proc print; run;

17
wdxmahone 发表于 2010-2-4 14:07:28
16# bobguy

挺好的,谢谢哈!不过我想要滞后20项,向前也要至少3、4十项的怎么样去编程,lag函数能不能做到,不可能手工去操作的。。。

18
wdxmahone 发表于 2010-2-4 15:22:48
14# soporaeternus2

您这个程序有点小问题,如果多加入一个变量的话,就会出现许多重复的内容,致使运算时间特别长,我的原始数据算了将近3个小时,而且最后还得通过merge去除一些不对的记录。。。
比如您select语句让其输出a.stkcd,a.price就会有很多重复的变量,如果再在原来的数据中加入另一个变量,且让其输出来,更会有很多不同的结果了,这使得数据量很大,我那个数据最后得出来的结果有32G。。。。

19
soporaeternus2 发表于 2010-2-4 16:46:57
我那个程序原始数据只能是4个变量,就是你开始说的那种结构
如果要对n个变量来做,请说明具体的逻辑,需要改动程序的

20
wdxmahone 发表于 2010-2-4 20:51:47
19# soporaeternus2
也不是n个变量,就是多了一两个变量,结果就会出现一些奇怪的结果,比如您可以将第14楼您写的程序的a.stkcd变成两个变量a.stkcd, a.price就会出现比较怪的结果:
                                                      SAS 系统             2010年02月04日 星期四 下午08时44分57秒   2
          Obs    stkcd    price          date    mark     a_2      a_1       a0       a1       a2       a3
            1     00      11.87    2009-01-03      1     11.55    12.01    12.03    12.00    11.56    11.87
            2     00      12.01    2009-01-03      1     11.55    12.01    12.03    12.00    11.56    11.87
            3     00      11.56    2009-01-03      1     11.55    12.01    12.03    12.00    11.56    11.87
            4     00      12.03    2009-01-03      1     11.55    12.01    12.03    12.00    11.56    11.87
            5     00      11.55    2009-01-03      1     11.55    12.01    12.03    12.00    11.56    11.87
            6     00      12.00    2009-01-03      1     11.55    12.01    12.03    12.00    11.56    11.87
            7     00      11.87    2009-01-06      1     12.01    12.03    12.00    11.56    11.87     0.00
            8     00      12.00    2009-01-06      1     12.01    12.03    12.00    11.56    11.87     0.00
            9     00      12.01    2009-01-06      1     12.01    12.03    12.00    11.56    11.87     0.00
           10     00      11.55    2009-01-06      1     12.01    12.03    12.00    11.56    11.87     0.00
           11     00      12.03    2009-01-06      1     12.01    12.03    12.00    11.56    11.87     0.00
           12     00      11.56    2009-01-06      1     12.01    12.03    12.00    11.56    11.87     0.00
           13     01      10.01    2009-01-02      1      0.00     0.00    10.01    10.03    10.00    10.56
           14     01      11.11    2009-01-02      1      0.00     0.00    10.01    10.03    10.00    10.56
           15     01      10.87    2009-01-02      1      0.00     0.00    10.01    10.03    10.00    10.56
           16     01      10.03    2009-01-02      1      0.00     0.00    10.01    10.03    10.00    10.56
           17     01      10.00    2009-01-02      1      0.00     0.00    10.01    10.03    10.00    10.56
           18     01      10.56    2009-01-02      1      0.00     0.00    10.01    10.03    10.00    10.56
           19     01      10.03    2009-01-03      1      0.00    10.01    10.03    10.00    10.56    10.87
           20     01      10.00    2009-01-03      1      0.00    10.01    10.03    10.00    10.56    10.87
           21     01      10.56    2009-01-03      1      0.00    10.01    10.03    10.00    10.56    10.87
           22     01      11.11    2009-01-03      1      0.00    10.01    10.03    10.00    10.56    10.87
           23     01      10.01    2009-01-03      1      0.00    10.01    10.03    10.00    10.56    10.87
           24     01      10.87    2009-01-03      1      0.00    10.01    10.03    10.00    10.56    10.87
           25     01      10.03    2009-01-07      1     10.03    10.00    10.56    10.87    11.11     0.00
           26     01      10.00    2009-01-07      1     10.03    10.00    10.56    10.87    11.11     0.00
           27     01      10.56    2009-01-07      1     10.03    10.00    10.56    10.87    11.11     0.00
           28     01      10.87    2009-01-07      1     10.03    10.00    10.56    10.87    11.11     0.00
           29     01      11.11    2009-01-07      1     10.03    10.00    10.56    10.87    11.11     0.00
           30     01      10.01    2009-01-07      1     10.03    10.00    10.56    10.87    11.11     0.00



这个最后倒是不难解决,但是可能这样会造成运行时间比较长,我的那些数据运行了3个小时,最后生成32G的文件,很恐怖,还是找了一个比较好的电脑才做出来的。

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

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