I wonder if there is an effective (without loops) method of joining two lists by names of their elements.
I checked here but this did not help me as well as tried to access names from sapply()
as on the answer from here.
Say I have the following lists:
mylist1 <- list(region1 = 1:3, region2 = 5:7)
> mylist1
$region1
[1] 1 2 3
$region2
[1] 5 6 7
and
mylist2 <- list(region1 = "#E8C506", region2 = "#F3B508")
$region1
[1] "#E8C506"
$region2
[1] "#F3B508"
How can I get joined list by element names:
mylist3 <- list(region1 = list(1:3, "#E8C506"), region2 = list(5:7, "#F3B508"))
> mylist3
$region1
$region1[[1]]
[1] 1 2 3
$region1[[2]]
[1] "#E8C506"
$region2
$region2[[1]]
[1] 5 6 7
$region2[[2]]
[1] "#F3B508"
CodePudding user response:
Relying heavily on the answers from @Ajar and @Flodel to Combine/merge lists by elements names, this maps into list
's instead of a vectors (c
) to achieve your end:
Using base
:
keys <- unique(c(names(mylist1), names(mylist2)))
setNames(mapply(list, mylist1[keys], mylist2[keys], SIMPLIFY = FALSE), keys)
Using purrr
:
library(purrr)
cat_lists <- function(list1, list2) {
keys <- unique(c(names(list1), names(list2)))
map2(list1[keys], list2[keys], list) |>
set_names(keys)
}
reduce(list(mylist1, mylist2), cat_lists)
Output:
$region1
$region1[[1]]
[1] 1 2 3
$region1[[2]]
[1] "#E8C506"
$region2
$region2[[1]]
[1] 5 6 7
$region2[[2]]
[1] "#F3B508"
CodePudding user response:
If the elements are identical in both lists you can use purrr::transpose()
:
library(purrr)
transpose(list(mylist1, mylist2))
$region1
$region1[[1]]
[1] 1 2 3
$region1[[2]]
[1] "#E8C506"
$region2
$region2[[1]]
[1] 5 6 7
$region2[[2]]
[1] "#F3B508"
Note tranpose()
uses the first list as a template and matches subsequent list elements by name, so if the elements are different across lists, you need to ensure all names are first present in the first list, e.g.:
mylist3 <- list(region1 = 1:3, region2 = 5:7, region3 = 5:7)
mylist4 <- list(region1 = "#E8C506", region2 = "#F3B508", region4 = "#F00008")
l <- list(mylist3, mylist4)
l_names <- unique(unlist(lapply(l, names)))
mylist3[l_names] <- mylist3[l_names]
transpose(list(mylist3, mylist4))
$region1
$region1[[1]]
[1] 1 2 3
$region1[[2]]
[1] "#E8C506"
$region2
$region2[[1]]
[1] 5 6 7
$region2[[2]]
[1] "#F3B508"
$region3
$region3[[1]]
[1] 5 6 7
$region3[[2]]
NULL
$region4
$region4[[1]]
NULL
$region4[[2]]
[1] "#F00008"
CodePudding user response:
I hope this works.
list12 <- mapply(list, mylist1 , mylist2 , SIMPLIFY=FALSE)