为移动平均线及其他滚动函数补全初始值的R实现方法
实现可变窗口的滚动计算(前k-1期用逐步窗口填充)
现有数据集
先创建测试数据集:
library(dplyr) library(zoo) df <- data.frame(date = seq.Date(from = "2025-01-01", to = "2025-01-10"), value = 1:10) df #> date value #> 1 2025-01-01 1 #> 2 2025-01-02 2 #> 3 2025-01-03 3 #> 4 2025-01-04 4 #> 5 2025-01-05 5 #> 6 2025-01-06 6 #> 7 2025-01-07 7 #> 8 2025-01-08 8 #> 9 2025-01-09 9 #> 10 2025-01-10 10
当前计算的问题
使用rollapply计算5期简单移动平均线时,前4个结果为NA:
df |> mutate(value_roll = rollapply(value, width = 5, FUN = mean, fill = NA, align = "right")) #> date value value_roll #> 1 2025-01-01 1 NA #> 2 2025-01-02 2 NA #> 3 2025-01-03 3 NA #> 4 2025-01-04 4 NA #> 5 2025-01-05 5 3 #> 6 2025-01-06 6 4 #> 7 2025-01-07 7 5 #> 8 2025-01-08 8 6 #> 9 2025-01-09 9 7 #> 10 2025-01-10 10 8
期望效果
对于阶数为k的滚动计算,前k-1个值分别用1到k-1期的滚动结果填充,示例如下:
#> date value value_roll #> 1 2025-01-01 1 1 #> 2 2025-01-02 2 1.5 #> 3 2025-01-03 3 2 #> 4 2025-01-04 4 2.5 #> 5 2025-01-05 5 3 #> 6 2025-01-06 6 4 #> 7 2025-01-07 7 5 #> 8 2025-01-08 8 6 #> 9 2025-01-09 9 7 #> 10 2025-01-10 10 8
简便实现方式
可以直接利用zoo包中rollapply的partial = TRUE参数,或者使用默认右对齐的rollapplyr配合该参数,它会自动对前k-1个元素使用逐步增大的窗口计算:
1. 滚动均值示例
df |> mutate(value_roll = rollapplyr(value, width = 5, FUN = mean, partial = TRUE))
运行结果与期望完全一致。
2. 滚动求和示例
df |> mutate(value_sum = rollapplyr(value, width = 5, FUN = sum, partial = TRUE)) #> date value value_sum #> 1 2025-01-01 1 1 #> 2 2025-01-02 2 3 #> 3 2025-01-03 3 6 #> 4 2025-01-04 4 10 #> 5 2025-01-05 5 15 #> 6 2025-01-06 6 20 #> 7 2025-01-07 7 25 #> 8 2025-01-08 8 30 #> 9 2025-01-09 9 35 #> 10 2025-01-10 10 40
3. 滚动标准差示例
df |> mutate(value_sd = rollapplyr(value, width = 5, FUN = sd, partial = TRUE)) #> date value value_sd #> 1 2025-01-01 1 NA #> 2 2025-01-02 2 0.7071068 #> 3 2025-01-03 3 1.0000000 #> 4 2025-01-04 4 1.2909944 #> 5 2025-01-05 5 1.5811388 #> 6 2025-01-06 6 1.5811388 #> 7 2025-01-07 7 1.5811388 #> 8 2025-01-08 8 1.5811388 #> 9 2025-01-09 9 1.5811388 #> 10 2025-01-10 10 1.5811388
注:单个元素无法计算标准差,所以第一行结果为NA,符合逻辑。
另外,也可以手动指定宽度序列(如width = seq_len(nrow(df)))实现,但partial = TRUE是更简洁的官方解决方案,支持所有可用于rollapply的函数。
内容的提问来源于stack exchange,提问作者Marcus Nunes
相关产品推荐
相关产品推荐

