正好有空,写了点注释,实在不擅长写......
- %MACRO MCR01(before,after);
- /*before:mark=1记录前需要转置的记录数*/
- /*after:mark=1记录后需要转置的记录数*/
- /*每个stkcd下每条记录按date唯一顺序标记*/
- proc sort data=a;by stkcd date;run;quit;
- data a;
- set a;
- by stkcd date;
- if first.stkcd then i=0;
- i+1;
- run;
- /*需要输出的date 以及它们的标记*/
- data b;
- set a(where=(mark=1) keep=stkcd i mark rename=(i=i_0));
- drop mark;
- run;
- proc sql;
- create table c as
- select
- .stkcd
- /*date输出*/
- ,sum(case when a.i=b.i_0 then date
- else 0
- end) as date format=yymmdd10.
- /*mark输出*/
- ,sum(case when a.i=b.i_0 then 1
- else 0
- end) as mark
- /*mark=1前 第&before 条记录 转置为 变量 a_&before*/
- %do i_b=&before %to 1 %by -1;
- ,sum(case when b.i_0-a.i=%eval(&i_b) then price
- else 0
- end) as a_&i_b
- %end;
- /*a0记录*/
- ,sum(case when a.i=b.i_0 then price
- else 0
- end) as a0
- /*mark=1后 第&after 条记录 转置为 变量 a&after*/
- %do i_a=1 %to &after %by 1;
- ,sum(case when a.i-b.i_0=%eval(&i_a) then price
- else 0
- end) as a&i_a
- %end;
- from a a
- left join b b
- on a.stkcd=b.stkcd
- group by a.stkcd
- ,b.i_0
- ;
- quit;
- %MEND MCR01;
- data a;
- input stkcd $ date:yymmdd10. price mark;
- format date yymmdd10.;
- cards;
- 00 2009-01-01 11.55 0
- 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 1
- 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
- 01 2009-01-09 11.11 0
- ;
- run;
- %MCR01(1,1);
- %MCR01(2,3);
- %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