在嵌套DataFrame中生成无开头NA的向后滚动平均值
在嵌套DataFrame中计算带部分窗口的向后滚动平均值(避免前几行NA)
问题重现
使用dplyr处理嵌套DataFrame时,需要新增嵌套列,复制原数据并将所有数值列替换为最近5行的向后滚动平均值(前N行用前N个元素的平均值,N从1到5)。尝试用zoo包的rollmean并设置partial = TRUE,或自定义函数的rollapply,但前4行始终为NA,不符合预期。
测试代码:
library(tidyverse) library(zoo) example <- tibble("index" = c(rep(1, 5), rep(2, 5)), "data_a" = c(1:3, 1:2, 1:3, 1:2), "data_b" = c(2:4, 2:3, 2:4, 2:3)) %>% group_by(index) %>% nest() example_ra <- example %>% mutate(roll_mean = map(data, ~ mutate(.x, across( where(is.numeric), ~rollmean( ., k = 5, fill = NA, partial = TRUE, align = "right" ) ))))
期望与实际结果
- 期望:前4行分别为1、2、3、4个元素的平均值,第5行为5个元素的平均值
- 实际:前4行全为NA,仅第5行有正确值
问题原因
你在rollmean中设置了fill = NA,该参数会强制将窗口不足5行的位置填充为NA,直接抵消了partial = TRUE的作用——即使partial = TRUE已经计算出了前4行的部分窗口平均值,也会被fill = NA覆盖成NA。
解决方案
方案1:修正rollmean参数(最简方式)
去掉fill = NA参数,保留partial = TRUE即可让rollmean自动计算前4行的部分窗口平均值:
example_ra <- example %>% mutate(roll_mean = map(data, ~ mutate(.x, across( where(is.numeric), ~rollmean( ., k = 5, partial = TRUE, align = "right" ) ))))
方案2:用rollapply实现更灵活控制
如果需要自定义滚动计算逻辑(比如处理NA值),可以用rollapply,同样设置partial = TRUE:
example_ra <- example %>% mutate(roll_mean = map(data, ~ mutate(.x, across( where(is.numeric), ~rollapply( ., width = 5, FUN = mean, align = "right", partial = TRUE, na.rm = TRUE # 数据含NA时启用,避免结果出现NA ) ))))
结果验证
以index=1的子数据为例:
- 原
data_a:[1,2,3,1,2]→ 滚动平均值:[1, 1.5, 2, 1.75, 1.8] - 原
data_b:[2,3,4,2,3]→ 滚动平均值:[2, 2.5, 3, 2.75, 2.8]
完全符合预期输出。
内容的提问来源于stack exchange,提问作者Sr. Riv
相关产品推荐
相关产品推荐

