如何对数据集中的最后n个观察值进行计算 例如,如果我有10个观察,我想创建一个变量,它将另一个变量的最后5个值相加。请不要建议我滞后5次或使用模块( N )。我需要一个更优雅的解决方案。
使用下面的代码alpha是我拥有的数据集,而bravo是我需要的数据集。
data alpha;
input lima @@ ;
cards ;
3 1 4 21 3 3 2 4 2 5
;
run ;
data bravo;
input lima juliet;
cards;
3 .
1 .
4 .
21 .
3 32
3 32
2 33
4 33
2 14
5 16
;
run;
提前谢谢你!
答案 0 :(得分:0)
我可以提供相当难看的解决方案:
编辑:我已经以更加紧凑的方式添加了这个概念的实例。
input var1 $ var2;
cards;
aaa 3
aaa 5
aaa 7
aaa 1
aaa 11
aaa 8
aaa 6
bbb 3
bbb 2
bbb 4
bbb 6
;
run;
data step1;
set sourcetable;
by var1;
retain obs 0;
if first.var1 then obs = 0;
else obs = obs+1;
if obs >=5 then to_sum = var2;
run;
proc sql;
create table rezults as
select distinct var1, sum(to_sum) as needed_summs
from step1
group by var1;
quit;
答案 1 :(得分:0)
您可以在数据步骤中执行此操作,也可以使用SAS / ETS中的PROC EXPAND(如果可用)。
对于数据步骤,我们的想法是您从累积总和(summ
)开始,但要跟踪到目前为止添加的值的数量(ninsum
)。一旦达到5,就开始将累积和输出到目标变量(juliet
),然后从下一步开始减去滞后-5值,只存储最后五个值的总和。
data beta;
set alpha;
retain summ ninsum 0;
summ + lima;
ninsum + 1;
l5 = lag5(lima);
if ninsum = 6 then do;
summ = summ - l5;
ninsum = ninsum - 1;
end;
if ninsum = 5 then do;
juliet = summ;
end;
run;
proc print data=beta;
run;
然而,有一个程序可以执行所有类型的累积,移动窗口等计算:PROC EXPAND,其中这实际上只是一行。我们只是告诉它在宽度为5的窗口中计算向后移动的总和,并将前4个观察值设置为缺失(默认情况下,它会将你的序列扩展为左边的0')
proc expand data=alpha out=gamma;
convert lima = juliet / transformout=(movsum 5 trimleft 4);
run;
proc print data=gamma;
run;
修改强>
如果要进行更复杂的计算,则需要在保留变量中携带先前的值。我以为你想避免这种情况,但现在是:
data epsilon;
set alpha;
array lags {5};
retain lags1 - lags5;
/* do whatever calculation is needed */
juliet = 0;
do i=1 to 5;
juliet = juliet + lags{i};
end;
output;
/* shift over lagged values, and add self at the beginning */
do i=5 to 2 by -1;
lags{i} = lags{i-1};
end;
lags{1} = lima;
drop i;
run;
proc print data=epsilon;
run;
答案 2 :(得分:0)
万一有人读这个:) 我解决了它需要它解决的方式。虽然现在我更好奇两者中的哪一个(保留和我的解决方案)在计算/处理时间方面更优。
这是我的解决方案:
data bravo(keep = var1 summ);
set alpha;
do i=_n_ to _n_-4 by -1;
set alpha(rename=var1=var2) point=i;
summ=sum(summ,var2);
end;
run;