[英]Proc expand for irregular time series
如何使用 PROC EXPAND 计算出现中断的时间序列的移动平均线? 我正在寻找一种更有效的方法来进行此计算,因为由于服务器限制,大型数据集上的 DATA 步和 JOINS 需要很长时间才能执行。
数据:
data have(drop=i);
call streaminit(1);
do i = 1 to 20;
period = i;
if i > 10 then period = i + 5;
if i >17 then period = i + 6;
x = round(rand('uniform')*10,1.);
output;
end;
run;
│ period │ x │
├────────┼────┤
│ 1 │ 9 │
│ 2 │ 10 │
│ 3 │ 5 │
│ 4 │ 9 │
│ 5 │ 7 │
│ 11 │ 9 │
│ 12 │ 9 │
│ 13 │ 5 │
│ 15 │ 8 │
│ 16 │ 9 │
请注意,周期变量中有两个断点:5-11 和 13-15。
这是预期结果(3 个月移动平均线):
Proc sql;
create table want as
select a.period, a.x
,mean(b.x) as x_avg format=10.2
from have as a
left join have as b
on a.period -3 < b.period <= a.period
group by 1,2;
Quit;
│ period │ x │ x_avg │
├────────┼────┼───────┤
│ 1 │ 9 │ 9.00 │
│ 2 │ 10 │ 9.50 │
│ 3 │ 5 │ 8.00 │
│ 4 │ 9 │ 8.00 │
│ 5 │ 7 │ 7.00 │
│ 11 │ 9 │ 9.00 │
│ 12 │ 9 │ 9.00 │
│ 13 │ 5 │ 7.67 │
│ 15 │ 8 │ 6.50 │
│ 16 │ 9 │ 8.50 │
您可以通过一点修改使 SQL 更快。
proc sql noprint;
create table want2 as
select a.period, a.x ,mean(b1.x,b2.x,a.x) as x_avg format=10.2
from have as a
left join have as b1 on a.period -2 = b1.period
left join have as b2 on a.period -1 = b2.period
order by a.period;
quit;
使用proc timeseries
在每个间隙之间添加缺失值,然后使用method=none
通过proc expand
运行它。 我们将每天考虑间隔,因为它一次增加一个值。 过滤掉您的最终数据集,使x
没有缺失值。
proc timeseries data = have
out = have_ts;
id period interval=day setmissing=missing;
var x;
run;
proc expand data = have_ts
out = want(where=(NOT missing(x)) );
id period;
convert x = x_avg / method=none transform=(moveave 3);
run;
您需要使用proc datasets
将period
重新格式化为8.
因为proc timeseries
需要将其视为日期。
proc datasets lib=work nolist;
modify want;
format x 8.;
quit;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.