如何用purrr::map实现plyr::dlply返回命名列表的效果?
用purrr::map实现plyr::dlply的命名列表返回效果
我完全理解你的需求——想要用purrr::map实现和plyr::dlply一样返回以分组变量值命名的列表,而且你的场景是在带列表列的数据框上操作,之前找到的旧回答没覆盖这个场景对吧?下面我给你详细拆解实现方法:
先回顾plyr的实现方式
假设我们用经典的mtcars数据集,先看dlply怎么返回命名列表:
library(tidyverse) library(plyr) # 用dlply按cyl分组,对每组做线性回归,返回命名列表 dlply_output <- dlply(mtcars, "cyl", function(data) { lm(mpg ~ wt, data = data) }) # 查看结果结构——列表名称是cyl的取值:4、6、8 str(dlply_output, max.level = 1) #> List of 3 #> $ 4:List of 12 #> $ 6:List of 12 #> $ 8:List of 12
用purrr实现相同效果(列表列场景)
如果你的数据已经是嵌套后的列表列格式(比如用nest()生成的),只需要两步:用map处理列表列,再用分组变量给列表设置名称:
# 先创建带列表列的数据框 nested_df <- mtcars %>% group_by(cyl) %>% nest() %>% ungroup() # 用purrr处理并生成命名列表 purrr_output <- nested_df$data %>% # 对每个列表元素执行分析(这里是线性回归) map(~ lm(mpg ~ wt, data = .x)) %>% # 用分组变量cyl的值作为列表名称 set_names(nested_df$cyl) # 查看结果,和dlply完全一致 str(purrr_output, max.level = 1) #> List of 3 #> $ 4:List of 12 #> $ 6:List of 12 #> $ 8:List of 12
从原始数据直接处理的purrr方案
如果还没嵌套数据,也可以直接从原始数据分组处理,结合group_split和group_keys来获取分组名称:
# 拆分数据为分组列表 grouped_data <- mtcars %>% group_by(cyl) %>% group_split() # 获取分组变量的取值作为名称 group_names <- mtcars %>% group_by(cyl) %>% group_keys() %>% pull(cyl) # 生成命名列表 purrr_output2 <- grouped_data %>% map(~ lm(mpg ~ wt, data = .x)) %>% set_names(group_names)
为什么map本身不返回命名列表?
purrr::map默认只按元素顺序处理输入列表/向量,不会自动关联分组变量作为名称;而dlply因为你明确指定了分组参数,所以自动将分组变量的取值作为输出列表的名称。我们只需要手动用set_names补上这一步,就能实现和dlply完全一致的效果。
内容的提问来源于stack exchange,提问作者Indrajeet Patil
相关产品推荐
相关产品推荐

