1

I'd like to unlist a nested list with has some items as vectors. The problem is that unlist also splits up these vectors. How can I keep them as single items?

a) one level up (unlist parameter: recursive = F)

b) all levels (unlist parameter: recursive = T)

Here's the example:

list0 <- list(c(1,2),
              list(3,
                   c(4,5)
                   )
              )

> list0
[[1]]
[1] 1 2

[[2]]
[[2]][[1]]
[1] 3

[[2]][[2]]
[1] 4 5

If we unlist one level:

list1 <- unlist(list0, recursive = F)

we get:

> list1
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3

[[4]]
[1] 4 5

but, as I'd like to keep vectors as they are, I'd like to get:

[[1]]
[1] 1 2

[[2]]
[1] 3

[[3]]
[1] 4 5

Maybe one way is with a for loop, but I guess that would be slow if the number of lists is high.

Could anyone give me some hints, please?

Thanks in advance

jormaga
  • 179
  • 1
  • 1
  • 12

1 Answers1

1

For your example, the code below gives the expected result.

f <- function(x){
  if(is.atomic(x)){
    list(x)
  }else{
    x
  }
}

unlist(lapply(list0, f), recursive=FALSE)

But perhaps you need something which works with more nested levels, like:

f <- function(x){
  if(is.atomic(x)){
    list(x)
  }else{
    x
  }
}
g <- function(L){
  out <- unlist(lapply(L, f), recursive=FALSE)
  while(any(sapply(out, is.list))){
    out <- g(out)
  }
  out
}

list1 <- list(c(1,2),
              list(3, c(4,5)), 
              list(6, list(c(7,8)))
)
list1_flattened <- g(list1)

which gives:

> list1
[[1]]
[1] 1 2

[[2]]
[[2]][[1]]
[1] 3

[[2]][[2]]
[1] 4 5


[[3]]
[[3]][[1]]
[1] 6

[[3]][[2]]
[[3]][[2]][[1]]
[1] 7 8    

> list1_flattened
[[1]]
[1] 1 2

[[2]]
[1] 3

[[3]]
[1] 4 5

[[4]]
[1] 6

[[5]]
[1] 7 8
Stéphane Laurent
  • 59,551
  • 14
  • 99
  • 196