8

Say I have N lists that all have the same column names. I want to merge these such that I get a resulting list with same columns, but now containing entries from all N list. Here is a MWE showing what I want:

  ls<-list()
ls[[1]]<-list("a"=1,
              "b"=2)
    ls[[2]]<-list("a"=3,
                  "b"=4)

#how to write a one-liner that produces lsTotal, which is the union of ls[[1]] and ls[[2]]?

lsTotal<-list("a"=c(1,3),
              "b"=c(2,4))  

I found this thread, from which I can use Map(c, ls[[1]], ls[[2]]). However, writing it out is tedious if ls is very long. Is there a shortcut?

lmo
  • 37,904
  • 9
  • 56
  • 69
N08
  • 1,265
  • 13
  • 23

3 Answers3

7

One option is tidyverse

library(purrr)
library(dplyr)
transpose(ls) %>%
        map(unlist)

Or use Map with do.call

do.call(Map, c(f=c, ls))
#$a
#[1] 1 3

#$b
#[1] 2 4
akrun
  • 874,273
  • 37
  • 540
  • 662
3

Here is a simple two-liner with unlist and split.

# get a named vector
tmp <- unlist(ls)

# split on the names
split(unname(tmp), names(tmp))
$a
[1] 1 3

$b
[1] 2 4
lmo
  • 37,904
  • 9
  • 56
  • 69
2

I know this question already has a few answers but another option is to use Reduce with your Map to apply the Map to each of the elements successively in the list:

Reduce(function(x,y) Map(c,x,y), ls)
#$a
#[1] 1 3

#$b
#[1] 2 4

Or for a more complicated example, the results are:

ls <- list(list(a=1, b=2), list(a=3, b=4), list(a=2,b=4), list(a=5,b=2), list(a=3,b=2))

#$a
#[1] 1 3 2 5 3

#$b
#[1] 2 4 4 2 2
Mike H.
  • 13,960
  • 2
  • 29
  • 39