首页 > 解决方案 > 使用自适应窗口长度计算 data.table 中的滚动平均值

问题描述

我希望在具有自适应窗口的 data.table 中按组计算移动平均值,以便在时间序列的开头没有 NA。我知道如何使用 frollmean 和设置adaptive = TRUE 来做到这一点(例如参见jangorecki's response in this thread)。当我的 data.table 中的所有组的长度相同时,我可以获得相同的代码,但当组的大小不同时会出现错误。

例如,如果我的数据是

tmp = data.table(Gp = c(rep('A',6),rep('B',4)), Val = c(1,3,4,6,2,2,8,5,7,10))

我正在做长度为 3 的移动平均值,那么所需的响应是

> desired_output
    Gp  Val
 1:  A 1.00
 2:  A 2.00
 3:  A 2.67
 4:  A 4.33
 5:  A 4.00
 6:  A 3.33
 7:  B 8.00
 8:  B 6.50
 9:  B 6.67
10:  B 7.33

我尝试了以下方法:

mov_window_len = vector("list",2)
mov_window_len[[1]] = c(1,2,rep(3,4))
mov_window_len[[2]] = c(1,2,rep(3,2))
tmp[,lapply(.SD, frollmean, n = mov_window_len, align = "right", adaptive = TRUE), by = Gp]

但我收到一条错误消息length of integer vector(s) provided as list to 'n' argument must be equal to number of observations provided in 'x'

解决此问题的任何帮助将不胜感激。提前致谢。

标签: rdata.table

解决方案


您可以使用组索引.GRP来设置子集mov_window_len。这将为您提供每个组的正确长度。你只想拿frollmeanVal,所以没必要lapply

tmp[, frollmean(Val, n = mov_window_len[.GRP], align = "right", adaptive = TRUE), by = Gp]

#     Gp       V1
#  1:  A 1.000000
#  2:  A 2.000000
#  3:  A 2.666667
#  4:  A 4.333333
#  5:  A 4.000000
#  6:  A 3.333333
#  7:  B 8.000000
#  8:  B 6.500000
#  9:  B 6.666667
# 10:  B 7.333333

或者,可以将窗口长度添加到输入 data.table (Len下面的字段),因为它对应于每一行。

tmp[Gp=="A", Len:=mov_window_len[[1]]
    ][Gp=="B", Len:=mov_window_len[[2]]
     ][, .(Val, Len, RollVal=frollmean(Val, Len, adaptive=TRUE)), by=Gp]
#    Gp Val Len  RollVal
# 1:  A   1   1 1.000000
# 2:  A   3   2 2.000000
# 3:  A   4   3 2.666667
# 4:  A   6   3 4.333333
# 5:  A   2   3 4.000000
# 6:  A   2   3 3.333333
# 7:  B   8   1 8.000000
# 8:  B   5   2 6.500000
# 9:  B   7   3 6.666667
#10:  B  10   3 7.333333

推荐阅读