我有代码,在一个地方以一个数据帧列表结束,我真的想转换成一个单一的大数据帧。

我从之前的一个问题中得到了一些提示,这个问题试图做一些类似但更复杂的事情。

下面是我开始的一个例子(为了说明,这是非常简化的):

listOfDataFrames <- vector(mode = "list", length = 100)

for (i in 1:100) {
    listOfDataFrames[[i]] <- data.frame(a=sample(letters, 500, rep=T),
                             b=rnorm(500), c=rnorm(500))
}

我目前正在使用这个:

  df <- do.call("rbind", listOfDataFrames)

当前回答

这里有另一种方法可以做到这一点(只是将它添加到答案中,因为reduce是一个非常有效的功能工具,它经常被忽视为循环的替代品。在这个特定的情况下,这两种方法都没有比do.call快得多)

使用底数R:

df <- Reduce(rbind, listOfDataFrames)

或者,用tidyverse来形容:

library(tidyverse) # or, library(dplyr); library(purrr)
df <- listOfDataFrames %>% reduce(bind_rows)

其他回答

从purrr 1.0.0开始,一个新的选项是list_rbind:

library(purrr)
list_rbind(listOfDataFrames, names_to = "column_label")

这里有另一种方法可以做到这一点(只是将它添加到答案中,因为reduce是一个非常有效的功能工具,它经常被忽视为循环的替代品。在这个特定的情况下,这两种方法都没有比do.call快得多)

使用底数R:

df <- Reduce(rbind, listOfDataFrames)

或者,用tidyverse来形容:

library(tidyverse) # or, library(dplyr); library(purrr)
df <- listOfDataFrames %>% reduce(bind_rows)

在tidyverse中应该如何做:

df.dplyr.purrr <- listOfDataFrames %>% map_df(bind_rows)

为那些想要比较一些最近答案的人提供了一个更新的视觉效果(我想比较purrr和dplyr解决方案)。基本上我结合了@TheVTM和@rmf的答案。

代码:

library(microbenchmark)
library(data.table)
library(tidyverse)

dflist <- vector(length=10,mode="list")
for(i in 1:100)
{
  dflist[[i]] <- data.frame(a=runif(n=260),b=runif(n=260),
                            c=rep(LETTERS,10),d=rep(LETTERS,10))
}


mb <- microbenchmark(
  dplyr::bind_rows(dflist),
  data.table::rbindlist(dflist),
  purrr::map_df(dflist, bind_rows),
  do.call("rbind",dflist),
  times=500)

ggplot2::autoplot(mb)

会议信息:

sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

包版本:

> packageVersion("tidyverse")
[1] ‘1.1.1’
> packageVersion("data.table")
[1] ‘1.10.0’

使用dplyr包中的bind_rows():

bind_rows(list_of_dataframes, .id = "column_label")