Mayou
Mayou

Reputation: 8858

Spliting a list of lists into sublists

Consider the following (simple) list of lists:

big_lst = list(list(rnorm(3), rnorm(4)), list(rnorm(3), rnorm(4)))

#> big_lst
#[[1]]
#[[1]][[1]]
#[1]  0.63620243 -0.01875264 -2.77235708

#[[1]][[2]]
#[1]  1.0527421 -0.3302443  1.2028328 -0.4019282


#[[2]]
#[[2]][[1]]
#[1] -1.6071500 -0.2870488 -0.1432817

#[[2]][[2]]
#[1]  0.7149935 -0.3090975  1.0108511  1.0419313

From this list, I would like to create two sublists as follows:

Is there an easy way of doing that? I have the feeling this has to do with the method split but I wasn't able to make it work.

Thanks,

Upvotes: 0

Views: 1860

Answers (2)

Matthew Plourde
Matthew Plourde

Reputation: 44634

You could do something like this:

split(do.call(c, big_lst), 1:2)

Benchmarks:

big_lst <- rep(big_lst, 100)
josh <- function() do.call(mapply, c(list, big_lst, SIMPLIFY=FALSE))
matthew <- function() split(do.call(c, big_lst), 1:2)
microbenchmark(josh(), matthew())
# Unit: microseconds
#       expr   min    lq median    uq    max neval
#     josh() 351.5 362.4  375.5 397.0 3191.9   100
#  matthew() 142.6 147.6  151.8 159.1  239.3   100

Upvotes: 2

Josh O&#39;Brien
Josh O&#39;Brien

Reputation: 162471

## Better example data
big_lst <- list(list(1:2, LETTERS[1:2]), list(3:4, LETTERS[3:4]))

## Use do.call to construct and evaluate a call that will look like:
##     mapply(list, big_lst[[1]], ..., big_lst[[n]], SIMPLIFY=FALSE)
do.call(mapply, c(list, big_lst, SIMPLIFY=FALSE))
# [[1]]
# [[1]][[1]]
# [1] 1 2
# 
# [[1]][[2]]
# [1] 3 4
# 
# 
# [[2]]
# [[2]][[1]]
# [1] "A" "B"
# 
# [[2]][[2]]
# [1] "C" "D"

Upvotes: 2

Related Questions