我有两个列表,其元素名称部分重叠,我需要逐个元素地合并/组合成一个列表:
> lst1 <- list(integers=c(1:7), letters=letters[1:5],
words=c("two", "strings"))
> lst2 <- list(letters=letters[1:10], booleans=c(TRUE, TRUE, FALSE, TRUE),
words=c("another", "two"), floats=c(1.2, 2.4, 3.8, 5.6))
> lst1
$integers
[1] 1 2 3 4 5 6 7
$letters
[1] "a" "b" "c" "d" "e"
$words
[1] "two" "strings"
> lst2
$letters
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
$booleans
[1] TRUE TRUE FALSE TRUE
$words
[1] "another" "two"
$floats
[1] 1.2 2.4 3.8 5.6
我尝试使用 mapply ,它基本上按索引组合了两个列表(即:&#34; [[&#34;),,而我需要按名称将它们组合(即:&#34; $&#34;)。此外,由于列表具有不同的长度,因此应用了回收规则(结果相当不可预测)。
> mapply(c, lst1, lst2)
$integers
[1] "1" "2" "3" "4" "5" "6" "7" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
$letters
[1] "a" "b" "c" "d" "e" "TRUE" "TRUE" "FALSE" "TRUE"
$words
[1] "two" "strings" "another" "two"
$<NA>
[1] 1.0 2.0 3.0 4.0 5.0 6.0 7.0 1.2 2.4 3.8 5.6
Warning message:
In mapply(c, lst1, lst2) :
longer argument not a multiple of length of shorter
正如您可能想象的那样,我正在寻找的是:
$integers
[1] 1 2 3 4 5 6 7
$letters
[1] "a" "b" "c" "d" "e" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
$words
[1] "two" "strings" "another" "two"
$booleans
[1] TRUE TRUE FALSE TRUE
$floats
[1] 1.2 2.4 3.8 5.6
有没有办法实现这一目标? 谢谢!
答案 0 :(得分:39)
你可以这样做:
keys <- unique(c(names(lst1), names(lst2)))
setNames(mapply(c, lst1[keys], lst2[keys]), keys)
对任意数量的列表进行推广需要混合使用do.call
和lapply
:
l <- list(lst1, lst2, lst1)
keys <- unique(unlist(lapply(l, names)))
setNames(do.call(mapply, c(FUN=c, lapply(l, `[`, keys))), keys)
答案 1 :(得分:0)
我也使用grep
,不知道它是更好,更差还是等效!
l_tmp <- c(lst1, lst2, lst1)
keys = unique(names(l_tmp))
l = sapply(keys, function(name) {unlist(l_tmp[grep(name, names(l_tmp))])})
答案 2 :(得分:0)
tidyverse
位用户的flodel's answer更新:
list1 <- list(integers=c(1:7), letters=letters[1:5],
words=c("two", "strings"))
list2 <- list(letters=letters[1:10], booleans=c(TRUE, TRUE, FALSE, TRUE),
words=c("another", "two"), floats=c(1.2, 2.4, 3.8, 5.6))
input_list <- list(list1, list2, list1, list2)
我们要为输出列表中的每个元素精确地复制原始所需的输出两次。与涉及map2
,reduce
和{{1}的基础R
解决方案相比,使用do.call
和mapply
,我们可以更清楚地实现这一点。 }。首先,我们声明一个函数,该函数使用lapply
将两个列表按其命名元素组合在一起,然后通过c()
在输入列表中调用函数:
reduce
这给了我们我们想要的东西:
library(purrr)
cat_lists <- function(list1, list2) {
keys <- unique(c(names(list1), names(list2)))
map2(list1[keys], list2[keys], c) %>%
set_names(keys)
}
combined_output <- reduce(input_list, cat_lists)