如何用dplyr和purrr批量按对应分类列汇总以eff开头的数值列?
如何用dplyr和purrr批量按对应分类列汇总以eff开头的数值列?
这个需求太贴合实际工作场景了!手动一个个写分组汇总不仅麻烦,后续列数变多还得重复改代码,用dplyr搭配purrr就能优雅地批量处理,不管你有多少组categ_xx和eff_xx列都能自动搞定,下面一步步来实现:
首先,先加载需要的包,顺便把你的测试数据定义好:
library(dplyr) library(purrr) library(stringr) # 用来提取列名里的后缀 mydf <- tribble( ~categ_21, ~categ_22, ~eff_21, ~eff_22, "a", "b", 1, 5, "b", "b", 2, 6, "c", "c", 3, 7, "c", "a", 4, 8 )
接下来,我们先自动提取所有categ_开头列的后缀(比如21、22),这样后续不管新增多少组列,都不用手动修改这部分代码:
# 从categ列名里提取数字后缀 suffixes <- str_extract(names(mydf)[str_detect(names(mydf), "^categ_")], "(?<=categ_)\\d+")
然后用purrr::map遍历每个后缀,对每组categ_xx和eff_xx做分组求和,同时动态保留eff_xx的列名:
# 批量生成每组的汇总结果,存成列表 summary_list <- map(suffixes, function(suffix) { mydf %>% # 筛选当前后缀对应的categ和eff列,并重命名categ列统一为"categ" select(categ = starts_with(paste0("categ_", suffix)), eff = starts_with(paste0("eff_", suffix))) %>% group_by(categ) %>% # 动态生成eff_xx列名,求和(加na.rm是防止有缺失值报错) summarise(!!paste0("eff_", suffix) := sum(eff, na.rm = TRUE)) })
最后把列表里的所有汇总表通过categ列合并起来,就是你想要的最终结果了:
# 合并所有汇总表,按categ排序 result <- reduce(summary_list, full_join, by = "categ") %>% arrange(categ) # 查看结果 result #> # A tibble: 3 × 3 #> categ eff_21 eff_22 #> <chr> <dbl> <dbl> #> 1 a 1 8 #> 2 b 2 11 #> 3 c 7 7
这个方法的好处就是完全自动化,后续如果你的数据新增了categ_23和eff_23,代码不用做任何修改就能直接生成对应的汇总列,非常适合实际工作中列数较多的场景。
备注:内容来源于stack exchange,提问作者Damien Dotta
相关产品推荐
相关产品推荐

