将数据帧组合在R中元素名称上键入的两个不同列表中



我有两个列表list1list2,每个列表都包含通过名称唯一标识的数据帧或数据表。我想将基于数据集名称的list1list2组合起来。我希望这两个列表的元素都出现在组合列表中。我已经尝试了很多来自stackerflow的解决方案,如do.call(c, list1, list2)Map(c, list1, list2)mapplymergelist.join。我获得的最大成功是创建了数据帧名称的键,并将Map与键一起使用,但它们没有在组合列表中保留不匹配的元素,比如keys <- unique(c(names(list1), names(list2))combined_list <- Map(rbind, list1[keys], list2[keys])。但他们都没有按我想要的方式为我工作。

基本上,我想在两个列表中包含的同名数据集上执行rbind。列表可以具有不同的长度并且具有不同的元素,有时还具有重叠的元素。

list1list2的外观:

a <- data.frame(id = 1:5, type =c("a", "b", "c", "d", "e"))
b <- data.frame(id = 6:10, type =c("f", "g", "h", "i", "j"))
c <- data.frame(id = 11:15, type =c("k", "l", "m", "n", "o"))
list1 <- list(a=a,b=b,c=c)
a <- data.frame(id = 16:20, type =c("p", "q", "r", "s", "t"))
b <- data.frame(id = 21:25, type =c("u", "v", "w", "x", "y"))
e <- data.frame(id = 26:30, type =c("z", "ab", "ac", "ad", "ae"))
f <- data.frame(id = 31:35, type =c("ba", "bb", "bc", "bd", "be"))
list2 <- list(a=a,b=b,e=e, f=f)

预期的结果应该是这样的:

a <- data.frame(id = c(1:5, 16:20), type =c("a", "b", "c", "d", "e", "p", "q", "r", "s", "t"))
b <- data.frame(id = c(6:10,21:25), type =c("f", "g", "h", "i", "j", "u", "v", "w", "x", "y"))
c <- data.frame(id = 11:15, type =c("k", "l", "m", "n", "o"))
e <- data.frame(id = 26:30, type =c("z", "ab", "ac", "ad", "ae"))
f <- data.frame(id = 31:35, type =c("ba", "bb", "bc", "bd", "be"))
combined_list <- list(a=a, b=b, c=c, e=e, f=f)

非常感谢在这方面的任何回应。附言:这是我在SO上的第一篇帖子。:(

您可以尝试使用list1list2中的uniquenames,就像您已经尝试过的那样,然后将它们用于setnames:

keys <- unique(c(names(list1), names(list2)))
x <- setNames(Map(rbind, list1[keys], list2[keys]), keys)
identical(x, combined_list)
#[1] TRUE

或使用lapply:

x <- lapply(setNames(keys, keys), function(x) {rbind(list1[[x]], list2[[x]])})
identical(x, combined_list)
#[1] TRUE

如果我正确理解您的问题,可以选择将两个列表都放在一个data.frame/tibble中,然后按组划分为列表项:

library(purrr)
library(dplyr)
df_of_lists <- dplyr::union(list1 %>% 
purrr::map_df(as.data.frame, .id = 'name'),
list2 %>% 
purrr::map_df(as.data.frame, .id = 'name'))
split(df_of_lists, f = df_of_lists$name ) %>%
# in case you want to remove the new name colum
purrr::map( ~ .x %>% dplyr::select(-name))

对于任意数量的数据帧列表,也可以使用splitrbind:

ll <- do.call('c', list(list1, list2))
lapply(split(ll, names(ll)), function(x){
do.call('rbind', args = c(x, list(make.row.names = F)))
})
# $a
#    id type
# 1   1    a
# 2   2    b
# 3   3    c
# 4   4    d
# 5   5    e
# 6  16    p
# 7  17    q
# 8  18    r
# 9  19    s
# 10 20    t
# 
# $b
#    id type
# 1   6    f
# 2   7    g
# 3   8    h
# 4   9    i
# 5  10    j
# 6  21    u
# 7  22    v
# 8  23    w
# 9  24    x
# 10 25    y
# 
# $c
#   id type
# 1 11    k
# 2 12    l
# 3 13    m
# 4 14    n
# 5 15    o
# 
# $e
#   id type
# 1 26    z
# 2 27   ab
# 3 28   ac
# 4 29   ad
# 5 30   ae
# 
# $f
#   id type
# 1 31   ba
# 2 32   bb
# 3 33   bc
# 4 34   bd
# 5 35   be

最新更新