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

如何使用dplyr计算末行前最后n行的cummean值

问题背景

使用dplyr处理数据框时,需要计算每行之前最后2行的累计均值,以示例数据value = c(1,2,3,4)为例,遍历到值为4的行时,预期计算结果为(2+3)/2 = 2.5。
原有尝试代码如下,无法正常运行:

new_df -> df %>%
    summarise(
       roll_mean = cummean(value,-2)
    )
报错原因
  • dplyr内置的cummean()仅支持计算从首行到当前行的全量累计均值,只接受1个输入参数,不支持传入偏移量自定义计算窗口,传入-2会直接触发参数不匹配报错。
  • 原代码使用summarise()实现行级计算逻辑错误,summarise()会将多行结果折叠为单条汇总值,保留所有行的计算结果需要使用mutate()函数。
  • 原代码赋值方向写反,new_df -> df %>% ...会将空对象new_df赋值给df,覆盖原始数据,正确赋值方向应为new_df <- df %>% ...。
  • 需求本质是排除当前行、取前置2个值计算滚动均值,和原生cummean()的计算逻辑不匹配。
实现方案

方案1:tidyverse生态通用写法(推荐,适配任意窗口长度)

使用tidyverse官方的滚动计算包slider和dplyr搭配,逻辑灵活可扩展:

library(dplyr)
library(slider)

# 构造示例数据
df <- tibble(value = c(1,2,3,4))

df <- df %>%
  mutate(
    roll_mean = slide_dbl(
      .x = value,
      .f = ~mean(.x, na.rm = TRUE),
      .before = 2, # 取当前行之前最多2行数据
      .after = -1  # 排除当前行及之后的行
    )
  )

运行结果如下,完全符合预期:

valueroll_mean
1NA
21.0
31.5
42.5

如果后续需要调整窗口长度,只需要修改.before参数即可,比如要算之前3行的均值就改成.before = 3。

方案2:无额外依赖写法(固定窗口场景)

如果不想安装其他包,且窗口长度固定为2,可以直接用dplyr的lag()函数取前置位的值计算:

df <- df %>%
  mutate(
    roll_mean = (lag(value, 1) + lag(value, 2)) / 2
  )

运行结果和方案1完全一致,缺点是窗口长度变化时需要手动调整公式,灵活度较低。

注意事项
  • 前几行因为前置数据不足2条,返回NA属于正常情况,如果需要对边界行做特殊计算,可以在均值函数里补充规则,或者调整slider的.complete参数设置。
  • 如果数据存在分组,直接在mutate()前加group_by()即可,滚动计算会自动在每个分组内独立计算。

内容的提问来源于stack exchange,提问作者Samuel Disorbo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:42:25