R语言中是否存在不折叠数据框的分组操作函数?
解决方案:为数据框添加分组聚合列(保留所有行)
你需要的是分组后保留原数据行数并添加聚合列,核心是用mutate替代summarise,以下是具体实现:
方法一:使用dplyr的mutate(和你的代码风格一致)
在group_by(Name)之后用mutate生成新列,mutate会为每个分组的每一行重复计算好的均值,不会压缩行数:
library(dplyr) # 原始数据框 df <- tibble( Name = c(rep("John",4), rep("Annie",4), rep("Bill",4)), Round = rep(1:4,3), Points = c(6,4,6,8,7,4,3,6,4,5,8,5) ) # 添加Avg.points列 df <- df %>% group_by(Name) %>% mutate(Avg.points = mean(Points, na.rm = TRUE)) %>% ungroup() # 可选操作,取消数据框的分组状态 print(df)
运行结果完全符合你的需求:
# A tibble: 12 × 4 Name Round Points Avg.points <chr> <int> <dbl> <dbl> 1 John 1 6 6 2 John 2 4 6 3 John 3 6 6 4 John 4 8 6 5 Annie 1 7 5 6 Annie 2 4 5 7 Annie 3 3 5 8 Annie 4 6 5 9 Bill 1 4 5.5 10 Bill 2 5 5.5 11 Bill 3 8 5.5 12 Bill 4 5 5.5
方法二:使用base R的ave函数
如果不想加载dplyr,base R的ave函数专门用来给每个分组生成重复的聚合值,一行代码就能搞定:
df$Avg.points <- ave(df$Points, df$Name, FUN = function(x) mean(x, na.rm = TRUE))
你之前的方法问题出在哪?
- 用
summarise的问题:summarise的作用是聚合分组,把每个组压缩成一行,所以会丢失原数据的大部分行;而mutate是在原数据基础上添加列,每个组的所有行都会得到对应的聚合结果。 - 多分组的问题:加入
Round和Points到分组条件后,每个分组变成了「玩家+轮次+单轮得分」,此时计算的是每个小分组的均值(其实就是单轮得分本身),自然不是玩家的整体平均。
内容的提问来源于stack exchange,提问作者orpr0
相关产品推荐
相关产品推荐

