You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在嵌套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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:05:58