500 Stimmen

Eine Liste von Datenrahmen zeilenweise zu einem Datenrahmen zusammenfassen

Ich habe Code, der an einer Stelle mit einer Liste von Datenrahmen endet, die ich eigentlich in einen einzigen großen Datenrahmen konvertieren möchte.

Ich habe einige Hinweise von einem frühere Frage das etwas Ähnliches, aber Komplexeres vorhatte.

Hier ist ein Beispiel dafür, womit ich anfange (zur Veranschaulichung stark vereinfacht):

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))
}

Ich verwende dies derzeit:

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

23voto

yeedle Punkte 4593

Hier ist eine weitere Möglichkeit, dies zu tun (einfach zu den Antworten hinzufügen, weil reduce ist ein sehr effektives funktionales Werkzeug, das oft als Ersatz für Schleifen übersehen wird. In diesem speziellen Fall ist keine der beiden wesentlich schneller als do.call)

unter Verwendung von Base R:

df <- Reduce(rbind, listOfDataFrames)

oder unter Verwendung des Tidyverse:

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

14voto

Nick Punkte 2890

Wie es im Tidyverse gemacht werden sollte:

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

12voto

f0nzie Punkte 1036

Das Einzige, was die Lösungen mit data.table fehlt die Identifizierungsspalte, um zu wissen, aus welchem Datenrahmen der Liste die Daten stammen.

Etwa so:

df_id <- data.table::rbindlist(listOfDataFrames, idcol = TRUE)

Die idcol Parameter fügt eine Spalte ( .id ), die den Ursprung des in der Liste enthaltenen Datenrahmens identifiziert. Das Ergebnis würde in etwa so aussehen:

.id a         b           c
1   u   -0.05315128 -1.31975849 
1   b   -1.00404849 1.15257952  
1   y   1.17478229  -0.91043925 
1   q   -1.65488899 0.05846295  
1   c   -1.43730524 0.95245909  
1   b   0.56434313  0.93813197

11voto

Nova Punkte 4746

Ein aktualisiertes Bild für diejenigen, die einige der letzten Antworten vergleichen wollen (ich wollte die Lösung von purrr mit dplyr vergleichen). Im Grunde habe ich die Antworten von @TheVTM und @rmf kombiniert.

enter image description here

Code:

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)

Infos zur Sitzung:

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

Paket-Versionen:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X