如何在R中基于元素名称合并两个列表(含嵌套列表场景)
R语言按列表元素名称合并列表(含嵌套列表场景)
一、单层列表的合并(基于元素名称)
注意:你提供的MyList1和MyList2是未命名列表,第一步需要给列表元素添加对应名称(1-3),否则无法基于名称匹配合并。
步骤1:重新构造并命名列表
library(tibble) # 构造MyList1并命名 tib1_1 <- tibble(colA = c("AB", "AB", "BA", "BA"), colB = c("K", "K", "K", "K"), colC=c("TP", "TP", "ND", "ND") ) tib1_2 <- tibble(colA = c("CD", "AB", "BA", "BA"), colB = c("L", "L", "L", "L"), colC=c("TP", "ND", "ND", "ND") ) tib1_3 <- tibble(colA = c("CD", "AB", "BA"), colB = c("M", "M", "M"), colC=c("TP", "ND", "ND")) MyList1 <- list("1" = tib1_1, "2" = tib1_2, "3" = tib1_3) # 构造MyList2并命名 tib2_1 <- tibble(colA = c("AB", "AB"), colB = c("K", "K"), colC=c("TP", "ND") ) tib2_2 <- tibble(colA = c("CD"), colB = c("L"), colC=c("TP") ) tib2_3 <- tibble(colA = c("CD", "AB", "BA"), colB = c("M", "M", "M"), colC=c("TP", "ND", "ND")) MyList2 <- list("1" = tib2_1, "2" = tib2_2, "3" = tib2_3)
步骤2:按名称合并成嵌套列表
提供两种实现方式:
方法1:Base R实现
# 获取两个列表的共同名称(仅合并双方都存在的元素) common_names <- intersect(names(MyList1), names(MyList2)) # 遍历共同名称,将对应元素组合成子列表 merged_list <- lapply(common_names, function(nm) { list(list1_tib = MyList1[[nm]], list2_tib = MyList2[[nm]]) }) # 给合并后的列表元素命名 names(merged_list) <- common_names
方法2:tidyverse(purrr)实现(更简洁)
library(purrr) # 通用场景(名称顺序可能不同) merged_list <- map(common_names, ~list(list1_tib = MyList1[[.]], list2_tib = MyList2[[.]])) %>% set_names(common_names) # 特殊场景:两个列表名称完全一致且顺序相同时,可直接用map2 merged_list <- map2(MyList1, MyList2, ~list(list1_tib = ., list2_tib = .x)) %>% set_names(names(MyList1))
合并后结果结构:每个名称(如"1")下包含两个tibble,分别来自MyList1和MyList2。
二、嵌套列表的合并(基于名称)
假设你有两个嵌套列表,顶层元素为命名子列表,子列表内包含命名tibble,以下是按名称递归合并的方案:
构造嵌套列表示例
# 嵌套列表1 NestedList1 <- list( "1" = list(sub_tib1 = tibble(a = 1:3), sub_tib2 = tibble(b = 4:6)), "2" = list(sub_tib1 = tibble(a = 7:9), sub_tib2 = tibble(b = 10:12)) ) # 嵌套列表2(名称顺序与1不同,模拟真实场景) NestedList2 <- list( "2" = list(sub_tib1 = tibble(a = 13:15), sub_tib2 = tibble(b = 16:18)), "1" = list(sub_tib1 = tibble(a = 19:21), sub_tib2 = tibble(b = 22:24)) )
按名称合并嵌套列表
# 获取顶层共同名称 top_common <- intersect(names(NestedList1), names(NestedList2)) # 递归合并:先匹配顶层名称,再匹配子列表名称 merged_nested <- lapply(top_common, function(top_nm) { sub_list1 <- NestedList1[[top_nm]] sub_list2 <- NestedList2[[top_nm]] sub_common <- intersect(names(sub_list1), names(sub_list2)) # 合并子列表内的对应元素 lapply(sub_common, function(sub_nm) { list(from_list1 = sub_list1[[sub_nm]], from_list2 = sub_list2[[sub_nm]]) }) %>% set_names(sub_common) }) %>% set_names(top_common)
用tidyverse实现更简洁:
merged_nested <- map(top_common, ~{ map2(NestedList1[[.]], NestedList2[[.]], ~list(from_list1 = ., from_list2 = .x)) %>% set_names(names(NestedList1[[.]])) }) %>% set_names(top_common)
合并后结构:顶层为名称1、2,每个顶层元素下的子列表(如sub_tib1)包含两个来自不同嵌套列表的tibble。
内容的提问来源于stack exchange,提问作者ksweet
相关产品推荐
相关产品推荐

