Reputation: 1845
I want to combine two lists
list_1 <- list(LIST1 = list(list("a"), list("b"), list("c")))
list_2 <- list(LIST2 = list(list("1"), list("2"), list("3")))
combined_list <- list()
combined_list[[1]] <- c("a", "1")
combined_list[[2]] <- c("b", "2")
combined_list[[3]] <- c("c", "3")
I have a nasty for loop way of doing this but I'd like to clean it up using purrr maybe? Any help appreciated!!
Upvotes: 5
Views: 713
Reputation: 13731
Here's a variant that recursively concatenates two nested lists of the same structure and preserves that structure
# Add additional checks if you expect the structures of .x and .y may differ
f <- function(.x, .y)
if(is.list(.x)) purrr::map2(.x, .y, f) else c(.x, .y)
res <- f( list_1, list_2 )
# ...is identical to...
# list(LIST1 = list(list(c("a","1")), list(c("b","2")), list(c("c","3"))))
You can then unroll the structure as needed. For example, to get the desired output, you can do
purrr::flatten(purrr::flatten(res))
# [[1]]
# [1] "a" "1"
#
# [[2]]
# [1] "b" "2"
#
# [[3]]
# [1] "c" "3"
Upvotes: 3
Reputation: 1203
You can actually use this one line:
map2(list_1,list_2,map2,~paste(c(..1,..2)))[[1]]
Output:
[[1]]
[1] "a" "1"
[[2]]
[1] "b" "2"
[[3]]
[1] "c" "3"
Upvotes: 0
Reputation: 15072
There's a few odd things with your input and so I am not sure if this will wholly generalize to your real situation. If it does not, then please expand your example. Each list has only one element, for one, and the individual letters are also wrapped in a list of their own. I get around that by indexing the input lists with [[1]]
and flattening the output with as.character
.
list_1 <- list(LIST1 = list(list("a"), list("b"), list("c")))
list_2 <- list(LIST2 = list(list("1"), list("2"), list("3")))
library(purrr)
combined_list <- map2(list_1[[1]], list_2[[1]], c) %>%
map(as.character)
str(combined_list)
#> List of 3
#> $ : chr [1:2] "a" "1"
#> $ : chr [1:2] "b" "2"
#> $ : chr [1:2] "c" "3"
Created on 2019-11-07 by the reprex package (v0.3.0)
Upvotes: 2