使用group_by()和summarize()时自定义函数返回结果异常求助
问题描述
在使用dplyr的group_by()后调用summarize()时,自定义函数返回的每个分组结果完全相同,不符合预期且无错误/警告提示。目标是让自定义函数能够正常适配group_by()的分组逻辑。
相关代码
library(dplyr) # 数据 transect <- data.frame(acronym = c("ABEESC", "ABIBAL", "AMMBRE", "ANTELE", "ABEESC", "ABIBAL", "AMMBRE"), quad_id = c(1, 1, 1, 1, 2, 2, 2)) # 评分数据 c_scores <- data.frame(acronym = c("ABEESC", "ABIBAL", "AMMBRE", "ANTELE"), c = c(5, 6, 6, 10)) # 自定义函数 my_fun <- function(data, scores){ join <- left_join(data, scores, by = "acronym") mean <- mean(join$c) return(mean) } # 单独调用正常 my_fun(transect, c_scores) # 管道调用正常 transect %>% my_fun(., c_scores) # 分组后调用异常 transect %>% group_by(quad_id) %>% summarise(mean_c = my_fun(., scores = c_scores))
当前输出结果
| quad_id | mean_c |
|---|---|
| 1 | 6.29 |
| 2 | 6.29 |
期望输出结果
| quad_id | mean_c |
|---|---|
| 1 | 6.75 |
| 2 | 5.66 |
问题原因与解决方法
原因
group_by()生成的是分组tibble,但自定义函数中直接使用left_join时,没有正确识别分组逻辑——在summarise()中传递给my_fun的.实际上仍是完整的原始数据(dplyr的函数兼容机制导致未自动拆分分组),因此每次计算的都是全局均值,而非分组均值。
解决方法
以下三种方式均可解决问题:
方式1:修改自定义函数适配分组
调整函数内部逻辑,使用dplyr链式操作确保分组被正确处理:
my_fun <- function(data, scores){ data %>% left_join(scores, by = "acronym") %>% summarise(mean_c = mean(c, na.rm = TRUE)) %>% pull(mean_c) }
重新运行分组代码即可得到正确结果。
方式2:使用group_map遍历分组
通过group_map直接逐个处理每个分组数据:
transect %>% group_by(quad_id) %>% group_map(~ my_fun(.x, c_scores)) %>% tibble(mean_c = .) %>% mutate(quad_id = c(1, 2)) %>% select(quad_id, mean_c)
方式3:简化逻辑,无需自定义函数
该场景可直接通过dplyr原生操作完成,无需自定义函数,写法更简洁:
transect %>% left_join(c_scores, by = "acronym") %>% group_by(quad_id) %>% summarise(mean_c = mean(c, na.rm = TRUE))
内容的提问来源于stack exchange,提问作者ifoxfoot
相关产品推荐
相关产品推荐

