如何用dplyr对tibble各列自定义汇总并返回列表列?
解决方法:批量生成列表格式的自定义汇总结果
你的核心需求是让自定义汇总函数(返回行数随机的tibble)批量处理所有列,同时将每个列的结果以列表列的形式保存,避免因结果行数不一致导致的报错。这里有两种适配不同dplyr版本的方案:
方案一:使用dplyr的across(推荐,适配新版本dplyr)
across是dplyr 1.0.0+版本推荐的批量处理函数,替代了旧的summarise_all系列函数,语法更清晰灵活:
library(dplyr) library(tibble) # 你的自定义汇总函数 mysummary <- function(x) {quantile(x)[1:sample(1:5, 1)] %>% as_tibble} # 批量处理所有列,生成带.summary后缀的列表列 cars %>% summarise( across( everything(), # 选择所有列,也可以用cols()指定特定列 ~ list(mysummary(.x)), # 将每个列的汇总结果包装为列表 .names = "{col}.summary" # 设置新列名规则:原列名+".summary" ) )
运行后会得到你期望的结果:1行2列的tibble,每个列都是列表类型,内部存储着行数随机的子tibble。
方案二:使用旧版summarise_all(适配dplyr 1.0.0之前版本)
如果你还在使用旧版dplyr,可以用summarise_all配合重命名来实现:
cars %>% summarise_all(~ list(mysummary(.x))) %>% # 对所有列应用函数并包装为列表 rename_with(~ paste0(.x, ".summary"), everything()) # 给列名添加.summary后缀
关键原理说明
为什么直接用summarise_all(mysummary)会失败?因为默认情况下,summarise会尝试将函数的输出展开为行,但你的mysummary返回的tibble行数是随机的(1-5行),不同列的结果行数不一致就会触发报错。而通过~ list(mysummary(.x))将结果包装为列表,summarise就会把每个列的结果作为单个列表元素存储在对应的列中,完美适配不同行数的输出。
内容的提问来源于stack exchange,提问作者crlwbm
相关产品推荐
相关产品推荐

