If I have a list of matrix or data.frame, we can use the following ways to bind the rows of all elements.
Firstly, I generate toy data
myList1 <- list(matrix(rnorm(2*3), ncol=2),
matrix(rnorm(2*3), ncol=2),
matrix(rnorm(2*3), ncol=2),
matrix(rnorm(2*3), ncol=2))
myList2 <- list(as.data.frame(matrix(rnorm(2*3), ncol=2)),
as.data.frame(matrix(rnorm(2*3), ncol=2)),
as.data.frame(matrix(rnorm(2*3), ncol=2)),
as.data.frame(matrix(rnorm(2*3), ncol=2)))
Now I list the alternative solutions
# solution 1
result1.1 <- do.call(rbind, myList1)
head(result1.1)
result1.2 <- do.call(rbind, myList2)
head(result1.2)
# solution 2
## plyr: the split-apply-combine paradigm for R
library(plyr)
result1.2.1 <- ldply(myList1, rbind)
head(result1.2.1)
###Error: All inputs to rbind.fill must be data.frames
result1.2.2 <- rbind.fill(myList1)
head(result1.2.2)
result2.2.1 <- ldply(myList2, rbind)
head(result2.2.1)
result2.2.2 <- rbind.fill(myList2)
head(result2.2.2)
# solution 3
## data.table: Enhanced data.frame
library(data.table)
###Error in rbindlist(myList1) : Item 1 of list input is not a data.frame, data.table or list
result1.3 <- rbindlist(myList1)
head(result1.3)
result2.3 <- rbindlist(myList2)
head(result2.3)
From the codes, we can see that
do.call(rbind, ), ldply
can work.do.call(rbind, ), ldply, rbind.fill, rbindlist
can work.And now benchmark for all solutions
# benchmark
## benchmark: a simple wrapper around system.time
library(rbenchmark)
benchmark(do.call(rbind, myList2), ldply(myList2, rbind), rbind.fill(myList2), rbindlist(myList2))
#############list of list#############################
# generate list of list
myList3 <- vector("list", 4)
for(i in 1:4){
myList3[[i]] <- vector("list", 2)
for(j in 1:2){
myList3[[i]][[j]] <- rnorm(3)
}
}
# bind each element of outer list
tempList <- lapply(myList3, function(z)do.call(rbind,z))
## selection operator "["
bind.ith.rows <- function(i) do.call(rbind, lapply(tempList, "[", i, TRUE))
nr <- nrow(tempList[[1]])
lapply(1:nr, bind.ith.rows)