如何在R语言中基于另一变量条件汇总数据?
问题:基于数值条件按组计算均值并汇总(长格式输出)
示例数据
dat <- data.frame(group = c("A", "A", "A", "A", "B", "B", "B", "B"), xy = c(1:4, 1:4), val = 1:8)
原始数据预览:
group xy val 1 A 1 1 2 A 2 2 3 A 3 3 4 A 4 4 5 B 1 5 6 B 2 6 7 B 3 7 8 B 4 8
期望输出
要求按group分组,分别计算xy在1-2、3-4范围内的val均值,输出为长格式:
group var val 1 A mean1_2 1.5 2 A mean3_4 3.5 3 B mean1_2 5.5 4 B mean3_4 7.5
尝试的错误方法
使用dplyr的summarise+case_when组合,结果不符合预期:
dat %>% group_by(group) %>% summarise(mean1_2 = case_when(xy %in% 1:2 ~ mean(val)), mean3_4 = case_when(xy %in% 3:4 ~ mean(val)))
运行结果:
`summarise()` has grouped output by 'group'. You can override using the `.groups` argument. # A tibble: 8 x 3 # Groups: group [2] group mean1_2 mean3_4 <chr> <dbl> <dbl> 1 A 2.5 NA 2 A 2.5 NA 3 A NA 2.5 4 A NA 2.5 5 B 6.5 NA 6 B 6.5 NA 7 B NA 6.5 8 B NA 6.5
解决方案
方法1:新增分组标签后双维度汇总
先给每条数据标记对应的均值分组,再按group+标签分组计算均值:
library(dplyr) dat %>% # 给xy值分配对应的分组标签 mutate(var = case_when( xy %in% 1:2 ~ "mean1_2", xy %in% 3:4 ~ "mean3_4" )) %>% # 同时按group和var分组,计算val的均值 group_by(group, var) %>% summarise(val = mean(val), .groups = "drop")
运行结果完全符合预期:
# A tibble: 4 x 3 group var val <chr> <chr> <dbl> 1 A mean1_2 1.5 2 A mean3_4 3.5 3 B mean1_2 5.5 4 B mean3_4 7.5
方法2:分条件筛选后合并结果
如果不想新增中间变量,可以分别筛选不同xy范围的数据,计算均值后合并:
library(dplyr) bind_rows( # 计算xy=1-2的均值 dat %>% filter(xy %in% 1:2) %>% group_by(group) %>% summarise(var = "mean1_2", val = mean(val), .groups = "drop"), # 计算xy=3-4的均值 dat %>% filter(xy %in% 3:4) %>% group_by(group) %>% summarise(var = "mean3_4", val = mean(val), .groups = "drop") ) %>% arrange(group) # 按group排序,和期望输出一致
错误方法的问题原因
之前的代码中,mean(val)计算的是整个group内所有val的均值(比如A组的mean(val)=2.5),而不是符合xy条件的子集均值;同时summarise不会自动压缩行数,导致每条原始观测都保留一行,最终结果混乱。
内容的提问来源于stack exchange,提问作者erc
相关产品推荐
相关产品推荐

