分组滚动平均值计算:如何用Base R实现两组三期数值变量的滚动平均?
基于Base R实现分组滚动平均值计算
问题说明
需对包含两个分组、三个观测周期的数值变量计算相邻观测值的滚动平均值,现有数据集及dplyr实现如下:
数据集代码
df <- data.frame( Day = c(1, 2, 3, 1, 2, 3), Id = c("A", "A", "A", "B", "B", "B"), Num = c(1, 2, 3, 1, 3, 9) )
已有的dplyr实现
library(dplyr) df %>% group_by(Id) %>% mutate(RollingAvg = (Num + lag(Num))/2)
Base R实现方案
以下提供两种清晰的Base R实现方式,均能按Id分组完成相邻数值的滚动平均值计算:
方案一:使用ave()函数(最简洁)
ave()是Base R原生的分组计算函数,可直接对目标向量按分组应用自定义逻辑:
df$RollingAvg <- ave(df$Num, df$Id, FUN = function(x) { # 第一个位置设为NA(无前置观测值),后续计算当前值与前一值的平均 c(NA, (x[-1] + x[-length(x)])/2) })
方案二:拆分-处理-合并(逻辑更直观)
通过拆分数据、逐个处理分组、再合并的流程,逻辑清晰易懂:
# 按Id分组拆分数据框 split_groups <- split(df, df$Id) # 遍历每个分组,计算滚动平均值 processed_groups <- lapply(split_groups, function(group) { group$RollingAvg <- c(NA, (group$Num[-1] + group$Num[-nrow(group)])/2) group }) # 合并所有分组,恢复原数据结构 df <- do.call(rbind, processed_groups) # 重置行号(可选操作) rownames(df) <- NULL
两种方案的输出结果与dplyr实现完全一致:
Day Id Num RollingAvg 1 1 A 1 NA 2 2 A 2 1.5 3 3 A 3 2.5 4 1 B 1 NA 5 2 B 3 2.0 6 3 B 9 6.0
内容的提问来源于stack exchange,提问作者Bradd
相关产品推荐
相关产品推荐

