前几行中的 SAS 最大值

SAS maximum value in preceding rows

我需要在不使用 PROC 的情况下计算每个 ID 和月份在过去 3 个月内的最大值(测量值)SQL.I 想知道我可以使用 RETAIN 语句来做到这一点,但是我不知道如何实现当前行与前两行Measure值比较的条件

我还需要 3 个月以上的时间来准备上述内容,因此任何不需要每个额外月份单独步骤的解决方案将不胜感激!

这是我的数据:

data have;
input month ID $ measure;
cards;
201501 A 0
201502 A 30
201503 A 60
201504 A 90
201505 A 0
201506 A 0
201501 B 0
201502 B 30
201503 B 0
201504 B 30
201505 B 60
;

这是我需要的:

data want;
input month ID $ measure max_measure_3m;
cards;
201501 A 0 0
201502 A 30 30
201503 A 60 60  
201504 A 90 90
201505 A 0 90
201506 A 0 90
201501 B 0 0
201502 B 30 30
201503 B 0 30
201504 B 30 30
201505 B 60 60
;

And here both tables: the one I have on the left and the one I need on the right

试试这个:

data want(drop=l1 l2 cnt tmp);
set have;
by id;
retain cnt max_measure_3m l1 l2;

if first.id then do;
    max_measure_3m = 0;
    cnt = 0;
    l1 = .;
    l2 = .;
end;

cnt = cnt + 1;

tmp = lag(measure);
if cnt > 1 then
    l1 = tmp;

tmp = lag2(measure);
if cnt > 2 then
    l2 = tmp;

if measure > l1 and measure > l2 then
    max_measure_3m = measure;
run; 

您可以使用大小适合您移动 window 的数组来执行此操作。就 windows 而言,我不确定您需要哪种类型的动态代码。如果您需要在 3 个月的基础上最多使用 4 或 5 个月,那么我建议使用 PROC EXPAND 而不是这些方法。 PROC EXPAND 的文档有一个很好的例子来说明如何做到这一点。

data want;
    set have;
    by id;
    array _prev(0:2) _temporary_;

    if first.id then
        do;
            call missing (of _prev(*));
            count=0;
        end;
    count+1;
    _prev(mod(count, 3))=measure;
    max=max(of _prev(*));
    drop count;
run;

proc expand data=test out=out method=none;
  by id;
  id month;

  convert x = x_movave3 / transformout=(movave 3);
  convert x = x_movave4 / transformout=(movave 4);
 run;