Question

I have one list which consists of another two lists, whose elements have partially overlapping names, which I need to merge/combine together into a single list, element by element.

In Combine/merge lists by elements names (list in list) a solution is provided how to solve this problem if the two lists are separate objects, i.e. not nested (again) in one single list.

Here is a wrap up of the example

# Generate some toy data    
library(digest)    
l.1 <- rep(list(list(c(10,20), NULL),
                list(c(10,20,30), NULL), 
                list(c(9,12,13), NULL)), 10000)
names(l.1) <- sapply(sample(1:30000, 30000, replace=FALSE), digest)
l.2 <- rep(list(list(NULL,c(1,0)),
                list(NULL,c(1,2,3))), 10000)
names(l.2) <- c(names(l.1)[1:10000], sapply(sample(30001:40000, 10000, replace=FALSE), digest))


# Apply the solution posted at
# https://stackoverflow.com/questions/23483421/combine-merge-lists-by-elements-names-list-in-list
keys <- unique(c(names(l.1), names(l.2)))
l  <- setNames(lapply(keys, function(key) {
  l1 <- l.1[[key]]
  l2 <- l.2[[key]]
  len <- max(length(l1), length(l2))
  lapply(seq(len), function(i) c(l1[[i]], l2[[i]]))
}), keys)

As stated above this solution is convenient when the number of separate lists (here 2) is small.

A scenario where those lists are nested within one single list is more realistic. Thus, one would be then able to perform the operation for all nested lists. It would not matter if there are 2 nested lists or 300.

An example for this would be:

l.new <- list(l.1, l.2)

To modify the solution above I know that the first line has to changed to:

keys <- unique(unlist(lapply(l.new, names)))

However I don't know how to adapt the second line

l  <- setNames(lapply(keys, function(key) {
    l1 <- l.1[[key]]
    l2 <- l.2[[key]]
    len <- max(length(l1), length(l2))
    lapply(seq(len), function(i) c(l1[[i]], l2[[i]]))
  }),
  keys)

I appreciate any help.

Was it helpful?

Solution

You just need to use lapply two more times with user-defined functions:

keys <- unique(unlist(lapply(l.new, names)))
l2  <- setNames(lapply(keys, function(key) {
  len <- max(unlist(lapply(l.new, function(x) length(x[[key]]))))
  lapply(seq(len), function(i) unlist(lapply(l.new, function(x) x[[key]][[i]])))
}), keys)
all.equal(l, l2)
# [1] TRUE
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top