0

Suppose we have list l which is a list of lists.

a <- list(c(1,2,3))
b <- list(c(4,5,6), c(7,8,9))
c <- list(c(10,11,12), c(13,14,15), c(16,17,18))

l <- list(a, b, c)

So l is a list of lists, where each of those lists itself contains at least one list.

Question

How can I make a function which can extract all the lowest level lists into a single list of lists?

# Goal
list(c(1,2,3), c(4,5,6), c(7,8,9), c(10,11,12), c(13,14,15), c(16,17,18))

Notes:

  • The example is a minimal reproducible example for which it would be possible to hard-code a solution, but it is important that the solution generalise, since the real problem has tens-of-thousands of lists each containing unknown numbers of lists - so a hard-coded solution definitely won't scale!

  • I hope to find a solution in base R, if possible.

A few things I've tried so far

Some unsuccessful attempts, mostly using sapply() and unlist():

sapply(l, function(x) { unlist(x) })
# [[1]]
# [1] 1 2 3
# 
# [[2]]
# [1] 4 5 6 7 8 9
# 
# [[3]]
# [1] 10 11 12 13 14 15 16 17 18

unlist(a)
# [1] 1 2 3

# unlist() seems to combine the elements of multiple lists into one list (not desired here)..
unlist(b)
# [1] 4 5 6 7 8 9

I thought the recursive = FALSE argument looked promising, but unfortunately I couldn't get it to do what I wanted either:

unlist(b, recursive = FALSE)
# [1] 4 5 6 7 8 9
stevec
  • 41,291
  • 27
  • 223
  • 311
  • Have you seen this? https://stackoverflow.com/questions/16300344/how-to-flatten-a-list-of-lists – Skaqqs Jan 06 '22 at 12:21
  • @Skaqqs thanks. I had seen it (linked to it in the question), but I hadn't applied it correctly! Thanks again – stevec Jan 06 '22 at 12:26

2 Answers2

2

Use unlist, non-recursive on your initial list.

unlist(l, recursive=FALSE)
# [[1]]
# [1] 1 2 3
# 
# [[2]]
# [1] 4 5 6
# 
# [[3]]
# [1] 7 8 9
# 
# [[4]]
# [1] 10 11 12
# 
# [[5]]
# [1] 13 14 15
# 
# [[6]]
# [1] 16 17 18
jay.sf
  • 60,139
  • 8
  • 53
  • 110
1

Just use unlist():

a <- list(c(1,2,3))
b <- list(c(4,5,6), c(7,8,9))
c <- list(c(10,11,12), c(13,14,15), c(16,17,18))
l <- list(a, b, c)

l.want <- list(c(1,2,3), c(4,5,6), c(7,8,9), c(10,11,12), c(13,14,15), c(16,17,18))

#Use unlist
l.func <- unlist(l, recursive = F)

all.equal(l.want, l.func)
# TRUE
jpsmith
  • 11,023
  • 5
  • 15
  • 36