r - 移动平均线变化窗口

标签 r dplyr data.table zoo rolling-computation

我有一个不平衡的面板,其中每个 ID 和月份都有某些观察结果(变量 x)。我正在尝试计算 x 的 6 个月滚动平均值,但仅限每年三月。我知道使用 zoo,我可以每次计算平均值,但我认为这在计算上是昂贵的。我有一个非常大的面板,所以最好先定义一个索引并将其传递给函数。另外,我的面板不平衡,因此有时我在给定的 3 月份拥有全部 6 个过去值,有时却没有。如果至少有 3 个可用值,我仍然想计算平均值。

这是一些示例代码和我迄今为止的解决方案:

library(data.table)
set.seed(1)
time=rep(seq(as.Date("2010-02-01"), length=42, by="1 month") - 1,2)
IDs=rep(letters[1:2],each=length(time))
DT <- data.table(time=time,
                 ID=IDs,
                 ind=rep(1:(2*length(time))),
                 row=1:(2*length(time)),
                 x=sample(2*length(time)))
DT

DT <- DT[!ind %in% c(11,12,26)]
DT


library(zoo)
DT[,movavg := if(length(x) >= 3){ rollapply(x, 6, sum, na.rm = FALSE,align = "right",fill = NA)}else{
  rep(NA,length(x))
},by=ID]
DT

目标是简单地显示每个三月的相应移动平均值,其中包含过去 6 个观测值。我不介意是否保留原始面板,即仅显示三月份的结果,或者仅提取三月份的值而不显示其他内容。

我的代码可以工作,但它每行/每月都会进行计算。我想要它做的是仅在定义的索引上工作。问题是,由于面板不平衡,游行之间的距离并不相等。例如,一年到另一年可能是 12 个月,但下一年到下一年可能是 10 个月,遗憾的是缺少 2 个观测值。还可以使用roll apply吗?任何有关数据表dplyr的提示都将受到高度赞赏。

最佳答案

如果问题中的这段代码给出了您想要的内容

DT[,movavg := if(length(x) >= 3){ rollapply(x, 6, sum, na.rm = FALSE,align = "right",fill = NA)}else{
  rep(NA,length(x))
},by=ID]

然后,第一个运行速度快了 2.8 倍,并给出了相同的结果,第二个使用 data.table 中的 frollsum 运行速度快了 4.8 倍。

DT[, movavg := rollsumr(x, 6, fill = NA), by = ID]
DT[, movavg := frollsum(x, 6), by = ID]

关于r - 移动平均线变化窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72276386/

相关文章:

r - 在 `r` 的 `caret` 包中训练测试拆分

r - 如何使用 purrr::pmap 调用 R 中的用户定义函数

r - 根据单列的内容将数据行添加到 tibble

r - 使用 dplyr 或其他解决方案从另一个 data.frame 更新 data.frame 的几行和几列

r - 使用循环或应用覆盖多个字符串变量

r - 使用dplyr将变量作为函数的默认参数

r - 等效于data.table中的ddply(...,transform,...)

r - 条件非对等连接

r - 在位置拆分 data.table

c - 如何使用 Rembedded 解析因子/数据帧