在R中按用户分组计算基于日期的月度滚动均值(Rollmean)
计算用户分组下过去一个月的ER均值
问题描述
需要按username分组,对每条记录的Date,计算**该日期过去一个月内(不含当前日期)**对应用户的ER均值。
原代码问题分析
第一种
rollmean方法:- 错误引用全局的
example$ER,应使用分组后的列 rollmean按行数窗口计算,不支持直接用日期范围作为窗口条件- 逻辑判断
Date > (Date %m-% months(1)) & Date < Date存在向量匹配错误,未针对每行日期单独筛选
- 错误引用全局的
第二种
runner方法:- 同样错误引用全局的
example$ER,应使用分组内的ER列 k=30是按行数而非天数窗口,需指定为k="30 days"来匹配日期范围
- 同样错误引用全局的
修正方案
方案1:使用runner包(高效推荐)
runner包专门处理基于时间或位置的滑动窗口,适合这类需求:
library(dplyr) library(runner) # 先按用户和日期排序,确保窗口计算正确 example <- example %>% arrange(username, Date) %>% group_by(username) %>% mutate( avgER_30days = mean_run( x = ER, # 要计算均值的列 idx = Date, # 用于定义窗口的日期列 k = "30 days", # 窗口范围:过去30天 lag = 1, # 排除当前行的ER值 na.rm = TRUE # 窗口无数据时返回NA而非错误 ) ) %>% ungroup()
方案2:纯dplyr实现(适合小数据集)
通过rowwise()逐行筛选组内符合日期范围的记录:
library(dplyr) library(lubridate) # 需要lubridate处理日期运算 example <- example %>% arrange(username, Date) %>% group_by(username) %>% rowwise() %>% mutate( avgER_30days = mean( ER[Date > (cur_data()$Date %m-% months(1)) & Date < cur_data()$Date], na.rm = TRUE ) ) %>% ungroup()
结果验证
以用户steves_的2020-04-06记录为例:
- 过去一个月范围是
2020-03-06至2020-04-05 - 该范围内仅存在
2020-03-24的ER值0.092 - 计算得到的
avgER_30days应为0.092,符合预期
内容的提问来源于stack exchange,提问作者Louisa Fritz
相关产品推荐
相关产品推荐

