0

I have a list of lists like out. In each list of list I have a dataframe (with the same structure, i.e. same variables).

out <- replicate(4, rep(list(NULL), 2), simplify = FALSE)

My desire is to rowbind all dataframes belonging to first list of lists, the second together (in my original exercise I have more than a 4 lists of 2 lists... For this example I would do something like the following:

dataframe1 <- rbind(out[[1]][[1]], out[[2]][[1]], out[[3]][[1]], out[[4]][[1]])
dataframe2 <- rbind(out[[1]][[2]], out[[2]][[2]], out[[3]][[2]], out[[4]][[2]])

Any idea on how to do it iteratively and more elegantly?

PS: Sorry for not sharing real data.

vog
  • 770
  • 5
  • 11

2 Answers2

2

Here is an approach using rlist and purr

do.call(rlist::list.zip, out) %>%
 purrr::map(~ do.call(rbind, .))

Or, with even more purrr:

library(purrr)

out %>%
  do.call(rlist::list.zip, .) %>%
  map(~ reduce(., rbind))
ktiu
  • 2,606
  • 6
  • 20
1

When your frames are all structured similarly or the same and you intend to to the same "thing" to all of them, it is generally best to work with a list of frames instead of individual elements.

out <- replicate(4, rep(list(mtcars[c(1,3),1:3]), 2), simplify = FALSE)
out[[1]][[1]]
#             mpg cyl disp
# Mazda RX4  21.0   6  160
# Datsun 710 22.8   4  108

lapply(1:2, function(ind) do.call(rbind, lapply(out, `[[`, ind)))
# [[1]]
#              mpg cyl disp
# Mazda RX4   21.0   6  160
# Datsun 710  22.8   4  108
# Mazda RX41  21.0   6  160
# Datsun 7101 22.8   4  108
# Mazda RX42  21.0   6  160
# Datsun 7102 22.8   4  108
# Mazda RX43  21.0   6  160
# Datsun 7103 22.8   4  108
# [[2]]
#              mpg cyl disp
# Mazda RX4   21.0   6  160
# Datsun 710  22.8   4  108
# Mazda RX41  21.0   6  160
# Datsun 7101 22.8   4  108
# Mazda RX42  21.0   6  160
# Datsun 7102 22.8   4  108
# Mazda RX43  21.0   6  160
# Datsun 7103 22.8   4  108

If you're already using dplyr or data.table, then these are relatively equivalent but often a little safer:

lapply(1:2, function(ind) data.table::rbindlist(lapply(out, `[[`, ind), fill = TRUE, use.names = TRUE))
lapply(1:2, function(ind) dplyr::bind_rows(lapply(out, `[[`, ind)))
r2evans
  • 141,215
  • 6
  • 77
  • 149