前几行中的 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;
我需要在不使用 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;