使用dplyr按ID分组计算条件rowMeans的问题求助
解决dplyr分组计算条件行均值的问题
问题背景
需要对每个user_id分组执行以下操作:
- 筛选出当前分组中数值型且列总和不等于0的列
- 计算这些列的行均值,新增为
rowAverage列
提供的示例数据:
dat <- as.Date("2021/08/04") len <- 4 seq(dat, by = "day", length.out = len) input <- data.frame( date = c(seq(dat, by = "day", length.out = len) , seq(dat, by = "day", length.out = len)), user_id = c(rep("aa",4),rep("bb",4)), var1 = c(1:4), var2 = c(4,7,23,9,0,0,0,0), var3 = c(0,0,0,0,4,8,2,7) )
期望输出:
output = data.frame( date = c(seq(dat, by = "day", length.out = len) , seq(dat, by = "day", length.out = len)), user_id = c(rep("aa",4),rep("bb",4)), var1 = c(1:4), var2 = c(4,7,23,9,0,0,0,0), var3 = c(0,0,0,0,4,8,2,7), rowAverage = as.numeric(c(rowMeans(input[1:4,3:4]), rowMeans(input[5:8,c(3,5)]))) )
原报错代码:
output = input %>% dplyr::group_by(user_id) %>% dplyr::mutate(rowAverage = rowMeans(select_if(function(x) {(is.numeric(x)) && (sum(x)=!0)})))
错误原因分析
- 语法错误:
sum(x)=!0是错误的逻辑判断写法,正确应为sum(x) != 0 - 分组处理逻辑错误:
select_if在mutate中直接调用时,会基于整个数据集筛选列,而非当前分组的子集;且select_if的用法不符合dplyr的最新语法(推荐用where()替代)
修正后的代码
library(dplyr) output <- input %>% group_by(user_id) %>% mutate( rowAverage = rowMeans( # 获取当前分组数据集,筛选数值型且列总和≠0的列 select(cur_data(), where(~is.numeric(.) && sum(.) != 0)), na.rm = TRUE # 可选:处理可能存在的NA值 ) ) %>% ungroup()
代码说明
cur_data():获取当前分组的数据集(自动排除分组列user_id)where(~is.numeric(.) && sum(.) != 0):筛选当前分组中符合条件的列,sum(.)计算的是当前分组内该列的总和rowMeans(..., na.rm=TRUE):计算筛选后列的行均值,添加na.rm=TRUE让代码更健壮,避免NA值导致计算失败
运行后结果与期望输出完全一致。
内容的提问来源于stack exchange,提问作者Telis
相关产品推荐
相关产品推荐

