如何用purrr简化嵌套列表a1数据框行绑定并保留层级名称
用purrr简化嵌套列表数据框合并并添加层级名称
现有嵌套列表L,所有子列表结构一致但名称不同,需求是将所有a1中的数据框行绑定,同时添加两列分别存储两层上层列表的名称。以下是原实现代码及用purrr包简化的方案:
原数据与原实现代码
嵌套列表数据
L=list(a=list(A=list(a1=data.frame(C1=1,C2=2),a2=20),B=list(a1=data.frame(C1=3,C2=4),a2=30)), b=list(C=list(a1=data.frame(C1=5,C2=6),a2=20),D=list(a1=data.frame(C1=7,C2=8),a2=30)))
原分步实现代码
# 提取各子列表中的a1 test=lapply(L,function(x) lapply(x,"[[",1)) # 内层数据框行绑定 test2=lapply(test,function(x) as.data.frame(do.call(rbind.data.frame,x))) # 添加第二层列表名称 test3=lapply(test2, function(x) {x$List_2_Name=row.names(x); return(x)}) # 外层行绑定并添加第一层列表名称 test4=data.table::rbindlist(test3,idcol = "List_1_Name")
期望输出
List_1_Name C1 C2 List_2_Name 1: a 1 2 A 2: a 3 4 B 3: b 5 6 C 4: b 7 8 D
purrr包简化实现方案
利用purrr::imap_dfr函数(支持同时遍历列表元素和名称,且自动行绑定结果),结合dplyr::mutate添加层级名称,代码更简洁:
library(purrr) library(dplyr) # 简化实现代码 result <- L %>% imap_dfr(function(l1, list1_name) { l1 %>% imap_dfr(function(l2, list2_name) { l2$a1 %>% mutate(List_2_Name = list2_name, List_1_Name = list1_name) }) }) %>% select(List_1_Name, C1, C2, List_2_Name) # 调整列顺序匹配期望输出
代码说明
imap_dfr:i表示可获取当前遍历的列表元素名称,dfr表示自动将遍历结果行绑定为数据框- 第一层遍历:处理最外层列表(
a、b),list1_name作为外层列表名称存入List_1_Name列 - 第二层遍历:处理各外层子列表内的元素(
A、B;C、D),list2_name作为中层列表名称存入List_2_Name列 - 最终通过
select调整列顺序,与原输出结构一致
执行结果
print(result) # List_1_Name C1 C2 List_2_Name # 1 a 1 2 A # 2 a 3 4 B # 3 b 5 6 C # 4 b 7 8 D
内容的提问来源于stack exchange,提问作者Stat
相关产品推荐
相关产品推荐

