如何在dplyr管道中复现plyr包dlply的“数据框入、列表出”功能?
在dplyr管道中复现plyr::dlply的功能
当然可以!既然你更倾向于使用dplyr,完全不需要依赖plyr就能实现“数据框入、列表出”的效果,而且操作更贴合tidyverse的风格,还能避免两个包的兼容性问题。下面分两种常见场景来演示:
1. 单纯按分组拆分数据框为列表
如果只是想把数据框按指定变量分组,然后拆成每个分组对应一个数据框的列表,用group_split()就可以完美实现,这对应dlply只做拆分的场景:
library(dplyr) # 示例:把mtcars按cyl分组拆成列表 split_result <- mtcars %>% group_by(cyl) %>% group_split() # 查看结果结构 str(split_result)
执行后你会得到一个列表,每个元素是对应cyl值的子数据框,和dlply(mtcars, .(cyl), identity)的效果完全一致。
如果需要给列表元素加上分组变量对应的名称(和dlply默认的命名逻辑对齐),可以搭配set_names():
named_split_result <- mtcars %>% group_by(cyl) %>% group_split() %>% set_names(unique(mtcars$cyl))
2. 分组后执行自定义操作再返回列表
如果你需要像dlply那样,对每个分组数据框执行特定操作(比如汇总、建模等)后返回列表结果,group_map()是最佳选择:
# 示例:对每个cyl分组计算mpg的均值和hp的最大值,结果以列表返回 operation_result <- mtcars %>% group_by(cyl) %>% group_map(~ .x %>% summarize(mean_mpg = mean(mpg), max_hp = max(hp))) # 查看结果 operation_result
这里的~ .x表示把每个分组的子数据框传给.x,你可以在后面的管道里任意组合dplyr或其他R函数,最终每个分组的计算结果会作为列表的一个元素返回,对应dlply(mtcars, .(cyl), function(x) {x %>% summarize(...)})的功能。
另外,如果你需要保留分组信息作为结果的一部分,也可以用group_modify(),不过它返回的是数据框;而group_map()专门用于返回列表,完全匹配你要的“列表出”需求。
为什么这些方法更好?
- 完全基于dplyr生态,不会和plyr产生兼容性冲突;
- 管道式写法更直观,符合tidyverse的代码风格;
- 函数参数和dplyr其他操作一致,学习成本更低。
内容的提问来源于stack exchange,提问作者C. Denney
相关产品推荐
相关产品推荐

