Combining two list in R

Viewed 42

I have two list l1 and l2 that I would like to combined to look like the expected, and get the mean using lapply. I would like it to be more effecient so that I don't have to type out the values everytime, because I would like to use this for a larger list. What might be a better way of accomplishing this?

l1 <- list(1,2,3,4,5)
l2 <- list(6,7,8,9,10)

expected <- list(c(1,6), c(2,7), c(3,8), c(4,9), c(5,10))
lapply(expected, mean)

Thank you!

3 Answers

We may use Map to concatenate (c) and get the mean

Map(c, l1, l2)
mapply(\(x, y) mean(c(x, y)), l1, l2)
[1] 3.5 4.5 5.5 6.5 7.5

Or instead of doing this in a loop, unlist both list to a vector, cbind to a matrix and get the rowMeans

rowMeans(cbind(unlist(l1), unlist(l2)))
[1] 3.5 4.5 5.5 6.5 7.5

Or may use pmean from kit

library(kit)
pmean(unlist(l1), unlist(l2))
[1] 3.5 4.5 5.5 6.5 7.5

Yet another possible solution:

rowMeans(do.call(rbind, Map(data.frame, A=l1, B=l2)))

#> [1] 3.5 4.5 5.5 6.5 7.5

Or using purrr::map2_dbl:

library(purrr)

map2_dbl(l1, l2, ~ mean(c(.x, .y)))

#> [1] 3.5 4.5 5.5 6.5 7.5

Another option is to use a simple formula on the two lists (which is slightly faster than pmean according to the benchmark below):

(unlist(l1) + unlist(l2))/2

# [1] 3.5 4.5 5.5 6.5 7.5

Benchmark

To determine the fastest, I created a slightly larger dataset of two lists that each have a length of 1,000. Then, I compared all of the methods posted so far.

l1 <- map(lapply(seq(1, 1000, 1), list), 1)
l2 <- map(lapply(seq(11, 1010, 1), list), 1)

enter image description here

-code

bm <- microbenchmark::microbenchmark(Map = lapply(Map(c, l1, l2), mean),
                               mapply = mapply(\(x, y) mean(c(x, y)), l1, l2),
                               rowMeans = rowMeans(cbind(unlist(l1), unlist(l2))),
                               pmean = pmean(unlist(l1), unlist(l2)),
                               rowMeans_Paul = rowMeans(do.call(rbind, Map(data.frame, A=l1, B=l2))),
                               map2_dbl = map2_dbl(l1, l2, ~ mean(c(.x, .y))),
                               unlist_baseR = (unlist(l1) + unlist(l2))/2,
                               times = 1000)
Related