I want to merge two lists keeping the index of each object:
mylist<-list(1,NULL,2)
otherlist<-list(NULL,3,NULL,4,5,6)
# Desired
list(1,3,2,4,5,6)
# my try:
suppressWarnings(mapply(c, mylist, otherlist) )
Answer should be universal
EDIT: In order to avoid proliferation of similar questions. I decided to request here also the possibility of keeping attributes (preferably with base).
mylist<-list(1,NULL,2)
attr(mylist[[1]],"at")<-"a"
attr(mylist[[3]],"at")<-"c"
otherlist<-list(NULL,3,NULL,4,5,6)
attr(otherlist[[2]],"at")<-"b"
attr(otherlist[[4]],"at")<-"d"
attr(otherlist[[5]],"at")<-"e"
attr(otherlist[[6]],"at")<-"f"
Here is an option where we create a logical index with lengths
(which will return 0 when there is NULL
) and use to assign the elements with mylist
unlisted
otherlist[lengths(otherlist) == 0] <- unlist(mylist)
otherlist
#[[1]]
#[1] 1
#[[2]]
#[1] 2
#[[3]]
#[1] 3
#[[4]]
#[1] 4
#[[5]]
#[1] 5
#[[6]]
#[1] 6
If we need to use Map
, make sure the lengths
are the same for the corresponding elements
otherlist[seq_along(mylist)] <- Map(c, otherlist[seq_along(mylist)], mylist)
For the updated example
i1 <- sapply(otherlist, is.null)
i2 <- !sapply(mylist, is.null)
otherlist[i1] <- mylist[i2]
otherlist
#[[1]]
#[1] 1
#attr(,"at")
#[1] "a"
#[[2]]
#[1] 3
#attr(,"at")
#[1] "b"
#[[3]]
#[1] 2
#attr(,"at")
#[1] "c"
#[[4]]
#[1] 4
#attr(,"at")
#[1] "d"
#[[5]]
#[1] 5
#attr(,"at")
#[1] "e"
#[[6]]
#[1] 6
#attr(,"at")
#[1] "f"
foo <- function(l1, l2) {
out <- vector(mode = "list", length = max(length(l1), length(l2)))
out[seq_along(l1)] <- l1
out[!lengths(out)] <- l2[!lengths(out)]
out
}
foo(mylist, otherlist2)
# [[1]]
# [1] 1
# attr(,"at")
# [1] "a"
#
# [[2]]
# [1] 3
# attr(,"at")
# [1] "b"
#
# [[3]]
# [1] 2
# attr(,"at")
# [1] "c"
#
# [[4]]
# [1] 5
# attr(,"at")
# [1] "e"
#
# [[5]]
# [1] 6
# attr(,"at")
# [1] "f"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With