将数据帧组合在两个不同的列表中,这些列表以 R 中的元素名称为键
Combine dataframes in two different lists keyed on the element name in R
我有两个列表 list1
和 list2
,每个列表都包含由名称唯一标识的数据框或数据表。我想将 list1
和 list2
键合到数据集的名称上。我希望两个列表的元素都出现在组合列表中。我已经尝试了很多来自 Whosebug 的解决方案,例如 do.call(c, list1, list2)
、Map(c, list1, list2)
或 mapply
、merge
、list.join
。我获得的最大成功是通过创建数据框名称的键并将 Map
与键一起使用,但它们没有在组合列表中保留不匹配的元素,例如 keys <- unique(c(names(list1), names(list2))
和 combined_list <- Map(rbind, list1[keys], list2[keys])
。但是 none 他们以我想要的方式为我工作。
基本上我想对两个列表中包含的同名数据集执行rbind
。这些列表的长度可能不同,并且包含不同的元素,有时还会有重叠的元素。
list1
和 list2
的样子:
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)
非常感谢在这方面的任何回应。
P.S。这是我在 SO 上的第一个 post。 :)
您可以尝试使用 list1
和 list2
中的 unique
names
,因为您已经尝试过,然后将它们用于 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.frames列表,这也可以用split
和rbind
来完成:
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
如果我正确理解你的问题,一个选项是将两个列表放在一个数据中。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))
我有两个列表 list1
和 list2
,每个列表都包含由名称唯一标识的数据框或数据表。我想将 list1
和 list2
键合到数据集的名称上。我希望两个列表的元素都出现在组合列表中。我已经尝试了很多来自 Whosebug 的解决方案,例如 do.call(c, list1, list2)
、Map(c, list1, list2)
或 mapply
、merge
、list.join
。我获得的最大成功是通过创建数据框名称的键并将 Map
与键一起使用,但它们没有在组合列表中保留不匹配的元素,例如 keys <- unique(c(names(list1), names(list2))
和 combined_list <- Map(rbind, list1[keys], list2[keys])
。但是 none 他们以我想要的方式为我工作。
基本上我想对两个列表中包含的同名数据集执行rbind
。这些列表的长度可能不同,并且包含不同的元素,有时还会有重叠的元素。
list1
和 list2
的样子:
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)
非常感谢在这方面的任何回应。 P.S。这是我在 SO 上的第一个 post。 :)
您可以尝试使用 list1
和 list2
中的 unique
names
,因为您已经尝试过,然后将它们用于 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.frames列表,这也可以用split
和rbind
来完成:
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
如果我正确理解你的问题,一个选项是将两个列表放在一个数据中。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))