Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in r combine a list of lists into one list

Tags:

list

r

I cannot find out can to get a list of all entry of the sublists? Here's a simple example, a list o lists:

listoflists <- list("A"=list(c(1,2,3),c(2,34,2)), "B" = list(c(1,2),c(2,3,2,1)), "C" = list(c("sdf",3,2)))
$A
$A[[1]]
[1] 1 2 3

$A[[2]]
[1]  2 34  2


$B
$B[[1]]
[1] 1 2

$B[[2]]
[1] 2 3 2 1


$C
$C[[1]]
[1] "sdf" "3"   "2"

I only found this sad way by using a for-loop:

listofvectors <- list()
for (i in 1:length(listoflists))  {listofvectors <- c(listofvectors, listoflists[[i]])}
like image 732
panuffel Avatar asked Apr 07 '17 15:04

panuffel


2 Answers

We can use the concatenate function (c) within do.call to flatten the nested list

res <- do.call(c, listoflists)
all.equal(listofvectors, res, check.attributes = FALSE)
#[1] TRUE

Or as @d.b mentioned in the comments, unlist with recursive = FALSE can also work

unlist(listoflists, recursive = FALSE)
like image 116
akrun Avatar answered Oct 27 '22 18:10

akrun


For your specific example, which does not have much nesting, you can also just use flatten from the "purrr" package.

library(purrr)
flatten(listoflists)

However, you don't specify the behavior you'd expect for more deeply nested lists. If you want to fully flatten a more deeply nested list, you can look at the LinearizeNestedList function by Akhil S Bhel.

Example:

LL <- list(listoflists, listoflists)
str(flatten(LL))  ## Same as `do.call(c, LL)`
# List of 6
#  $ A:List of 2
#   ..$ : num [1:3] 1 2 3
#   ..$ : num [1:3] 2 34 2
#  $ B:List of 2
#   ..$ : num [1:2] 1 2
#   ..$ : num [1:4] 2 3 2 1
#  $ C:List of 1
#   ..$ : chr [1:3] "sdf" "3" "2"
#  $ A:List of 2
#   ..$ : num [1:3] 1 2 3
#   ..$ : num [1:3] 2 34 2
#  $ B:List of 2
#   ..$ : num [1:2] 1 2
#   ..$ : num [1:4] 2 3 2 1
#  $ C:List of 1
#   ..$ : chr [1:3] "sdf" "3" "2"
str(LinearizeNestedList(LL))
# List of 10
#  $ 1/A/1: num [1:3] 1 2 3
#  $ 1/A/2: num [1:3] 2 34 2
#  $ 1/B/1: num [1:2] 1 2
#  $ 1/B/2: num [1:4] 2 3 2 1
#  $ 1/C/1: chr [1:3] "sdf" "3" "2"
#  $ 2/A/1: num [1:3] 1 2 3
#  $ 2/A/2: num [1:3] 2 34 2
#  $ 2/B/1: num [1:2] 1 2
#  $ 2/B/2: num [1:4] 2 3 2 1
#  $ 2/C/1: chr [1:3] "sdf" "3" "2"
like image 44
A5C1D2H2I1M1N2O1R2T1 Avatar answered Oct 27 '22 20:10

A5C1D2H2I1M1N2O1R2T1