1

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.

Community
  • 1
  • 1
majom
  • 7,863
  • 7
  • 55
  • 88

1 Answers1

2

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
josliber
  • 43,891
  • 12
  • 98
  • 133
  • Can you please change `keys <- unique(c(names(l.1), names(l.2)))` to `keys <- unique(unlist(lapply(l.new, names)))` for future reference. Somehow, this change does not go through the review process when I edit your post myself. – majom May 07 '14 at 10:06
  • A followup question for arbitrary lists element by element with respect to matched names https://stackoverflow.com/questions/51263678/r-combine-arbitrary-lists-element-by-element-with-respect-to-matched-names – Soumya Boral Jul 11 '18 at 19:15