使用dplyr的summarise+case_when分组聚合时重复行问题排查
问题原因及解决方案
错误原因
你的代码触发警告并输出重复行的核心问题是:summarise要求每个分组必须返回恰好一行结果,但原代码中name2的case_when逻辑会让多行分组(比如id=1)返回多行值:
- 当
n()>1时,.default = NA_character_会对组内每一行都生成一个NA,导致该分组输出2行; - dplyr 1.1.0+版本严格限制了
summarise的返回行数,因此抛出警告提示这种用法已被弃用。
修正后的代码
要实现每个id一行的输出,需要确保summarise中每个计算项都返回单行值。以下两种方法都可以解决问题:
方法1:使用if语句(更简洁)
library(dplyr, warn.conflicts = F) mock <- tibble::tribble(~id, ~name, ~year, 1, "xy", 2022, 1, "xyz", 2021, 2, "aaa", NA, 3, "xaa", 2021) mock %>% group_by(id) %>% summarise( condition = if(n() > 1) "problem" else NA_character_, name2 = if(n() == 1) name else NA_character_, .groups = "drop" # 可选:显式取消分组,避免后续操作混淆 )
方法2:修正case_when逻辑
如果坚持用case_when,需要确保每个分支返回单行值(比如用first(name)取组内唯一的name值):
mock %>% group_by(id) %>% summarise( condition = case_when( n() > 1 ~ "problem", TRUE ~ NA_character_ ), name2 = case_when( n() == 1 ~ first(name), TRUE ~ NA_character_ ), .groups = "drop" )
正确输出
运行修正后的代码会得到你期望的3行结果:
#> # A tibble: 3 × 3 #> id condition name2 #> <dbl> <chr> <chr> #> 1 1 problem <NA> #> 2 2 <NA> aaa #> 3 3 <NA> xaa
内容的提问来源于stack exchange,提问作者olivroy
相关产品推荐
相关产品推荐

