I think you will have to write your own recursive function here.
A function that takes on two lists, list1 and list2 . If a:
list1[[name]] exists, but not list2[[name]] , use list1[[name]] ;list1[[name]] exists, as well as list2[[name]] , and both of them are not lists, use list2[[name]] ;- otherwise, recursion with
list1[[name]] and list2[[name]] as new lists.
Something like:
myMerge <- function (list1, list2) { allNames <- unique(c(names(list1), names(list2))) merged <- list1 # we will copy over/replace values from list2 as necessary for (x in allNames) { # convenience a <- list1[[x]] b <- list2[[x]] if (is.null(a)) { # only exists in list2, copy over merged[[x]] <- b } else if (is.list(a) && is.list(b)) { # recurse merged[[x]] <- myMerge(a, b) } else if (!is.null(b)) { # replace the list1 value with the list2 value (if it exists) merged[[x]] <- b } } return(merged) }
Caveats - if your lists to be combined are weird, you might get weird output. For example:
a <- list( a=list(a=1, b=2), b=3 ) b <- list( a=2 )
Then your combined list has a=2, b=3 . This is because the value from b$a overrides the value from a$a , although a$a is a list (you did not specify what would happen if that was the case). However, simply changing myMerge to handle such cases. Just remember - use is.list to check if it is a list, and is.null(myList$a) to see if there is an entry a in myList .
Here is the "vectorized" version using sapply :
merge.lists <- function(a, b) { a.names <- names(a) b.names <- names(b) m.names <- sort(unique(c(a.names, b.names))) sapply(m.names, function(i) { if (is.list(a[[i]]) & is.list(b[[i]])) merge.lists(a[[i]], b[[i]]) else if (i %in% b.names) b[[i]] else a[[i]] }, simplify = FALSE) }
mathematical.coffee
source share