ciccioz
ciccioz

Reputation: 75

R rbind: concatenate each element of a nested list

I'm having hard times trying to concatenate data.frames that are elements of a list of lists in R. I have implented a first raw solution with a for-loop, but (of course) it becomes really slow as the length of the list grow.

(UPDATE: I have added the element "message" to each nested list)

Here the example code:

list1 = list()
list1[[1]] = list(df = data.frame(A = 1 : 10, B = 30 : 21), 
                  message = "first list")
list1[[2]] = list(df = data.frame(A = 11 : 20, B = 20 : 11), 
                  message = "second list")
list1[[3]] = list(df = data.frame(A = 21 : 30, B = 30 : 21), 
                  message = "third list")

dfFinal = data.frame()
for(nIndexList in 1 : length(list1)) {
  dfFinal = rbind(dfFinal, list1[[nIndexList]]$df)
}

Is there a faster way to do that (e.g., vectorization)?

Upvotes: 2

Views: 746

Answers (1)

markus
markus

Reputation: 26343

update

Based on the new requirement - each sublist now contains a dataframe and a vector - we must filter for data.frames

do.call(rbind, c(Filter(is.data.frame, unlist(list1, recursive = FALSE)),
                 make.row.names = FALSE))

initial answer (each sublist contained a sinlge dataframe only)

You might use unlist with argument recursive = FALSE and then do.call(rbind, ...)

do.call(rbind, c(unlist(list1, recursive = FALSE), make.row.names = FALSE))
#    A  B
#1   1 30
#2   2 29
#3   3 28
#4   4 27
#5   5 26
#6   6 25
#7   7 24
#8   8 23
#9   9 22
#10 10 21
#11 11 20
# ...

make.row.names = FALSE is passed to rbind as well.


If speed is a concern you might use data.table

data.table::rbindlist(unlist(list1, recursive = FALSE))

A tidyverse way would be

dplyr::bind_rows(purrr::flatten(list1))

Upvotes: 5

Related Questions