如何用R dplyr计算分组的降序滚动平均值?
在dplyr中按组计算降序滚动平均值的解决方案
你需要实现的是组内从当前行到组末尾的滚动平均值:即组内第1行计算所有行的均值,第2行计算第2到最后一行的均值,直到最后一行仅计算自身的均值。
原代码问题分析
你的原代码使用zoo::rollmean时,错误地将lead_time(行号)作为窗口长度,导致计算的是从当前行向前的滚动均值(前1个、前2个...),而非从当前行到末尾的均值。此外,align='left'的用法不符合你的需求场景。
解决方案
以下提供两种可靠的实现方式:
方法1:使用zoo包的rollapply(灵活定义窗口长度)
rollapply支持动态窗口长度,我们可以为每个行指定从当前行到末尾的窗口大小:
library(dplyr) library(zoo) the_df <- tibble(id=c(rep('x', 11),rep('y',11)), a=rep(10:0,2), b=rep(seq(100,0,by=-10),2)) result <- the_df %>% group_by(id) %>% mutate( # 对a、b列计算从当前行到末尾的滚动均值 across(c(a, b), ~ rollapply(., width = seq(n(), 1), FUN = mean, align = "left"), .names = "{.col}_run_avg") ) # 查看结果 result
width = seq(n(), 1):窗口长度从组内总行数n()递减到1,对应第1行窗口覆盖全组,第2行覆盖后n()-1行,以此类推。align = "left":确保窗口从当前行开始向右延伸到组末尾。
方法2:使用slider包(更直观的窗口定义)
slider包专为滚动计算设计,语法更简洁直观:
library(dplyr) library(slider) the_df <- tibble(id=c(rep('x', 11),rep('y',11)), a=rep(10:0,2), b=rep(seq(100,0,by=-10),2)) result <- the_df %>% group_by(id) %>% mutate( across(c(a, b), ~ slide_dbl(., mean, .after = Inf, .complete = FALSE), .names = "{.col}_run_avg") ) # 查看结果 result
.after = Inf:指定窗口包含当前行及之后的所有行(直到组末尾)。.complete = FALSE:允许窗口长度逐渐减小(最后几行仅包含自身或少量后续行)。
验证结果
以id='x'的a列为例:
- 第1行(
a=10)的a_run_avg为(10+9+...+0)/11=5,符合需求。 - 第10行(
a=1)的a_run_avg为1(仅自身)。 - 第11行(
a=0)的a_run_avg为0。
内容的提问来源于stack exchange,提问作者JFD
相关产品推荐
相关产品推荐

