rbindlist
ist eine optimierte Version von do.call(rbind, list(...))
, die dafür bekannt ist, dass sie bei der Verwendung langsam istrbind.data.frame
Wo zeichnet es sich wirklich aus?
Einige Fragen, die zeigen, wo rbindlist
Glanz ist
Schnelle vektorisierte Zusammenführung der Liste der Datenrahmen nach Zeilen
Probleme beim Konvertieren einer langen Liste von Datenrahmen (~ 1 Million) in einzelne Datenrahmen mit do.call und ldply
Diese haben Benchmarks, die zeigen, wie schnell es sein kann.
rbind.data.frame ist aus einem bestimmten Grund langsam
rbind.data.frame
führt viele Überprüfungen durch und stimmt mit dem Namen überein. (dh rbind.data.frame berücksichtigt die Tatsache, dass Spalten möglicherweise in unterschiedlicher Reihenfolge vorliegen und nach Namen übereinstimmen), rbindlist
führt diese Art der Überprüfung nicht durch und wird nach Position verbunden
z.B
do.call(rbind, list(data.frame(a = 1:2, b = 2:3), data.frame(b = 1:2, a = 2:3)))
## a b
## 1 1 2
## 2 2 3
## 3 2 1
## 4 3 2
rbindlist(list(data.frame(a = 1:5, b = 2:6), data.frame(b = 1:5, a = 2:6)))
## a b
## 1: 1 2
## 2: 2 3
## 3: 1 2
## 4: 2 3
Einige andere Einschränkungen von rbindlist
Früher hatte esfactors
aufgrund eines Fehlers, der inzwischen behoben wurde , Schwierigkeiten, damit umzugehen :
rbindlist zwei data.tables, wobei eine den Faktor und die andere den Zeichentyp für eine Spalte hat ( Bug # 2650 )
Es gibt Probleme mit doppelten Spaltennamen
siehe
Warnmeldung: in rbindlist (allargs): NAs durch Zwang eingeführt: möglicher Fehler in data.table? ( Bug # 2384 )
rbind.data.frame-Rownamen können frustrierend sein
rbindlist
kann mit lists
data.frames
und umgehen und data.tables
gibt eine data.table ohne Rücknamen zurück
Sie können mit do.call(rbind, list(...))
see in ein Wirrwarr von Rownamen geraten
Wie vermeide ich das Umbenennen von Zeilen, wenn ich rbind in do.call verwende?
Speichereffizienz
In Bezug auf Speicher rbindlist
wird in implementiert C
, so ist Speicher effizient, es verwendet setattr
, um Attribute durch Referenz festzulegen
rbind.data.frame
implementiert in ist R
, hat es eine Menge Zuweisung und Verwendungen attr<-
(und class<-
und rownames<-
von denen alle (intern) Kopien des erstellten data.frame erstellen.
attr<-
,class<-
und (glaube ich)rownames<-
alle ändern sich an Ort und Stelle.DF = data.frame(a=1:3); .Internal(inspect(DF)); tracemem(DF); attr(DF,"test") <- "hello"; .Internal(inspect(DF))
.rbind.data.frame
hat eine spezielle "Hijacking" -Logik - wenn das erste Argument a istdata.table
, ruft es.rbind.data.table
stattdessen auf, was ein wenig prüft und dannrbindlist
intern aufruft . Wenn Sie also bereitsdata.table
Objekte zum Binden haben, gibt es wahrscheinlich nur einen geringen Leistungsunterschied zwischenrbind
undrbindlist
.rbindlist
nach Namen (use.names=TRUE
) übereinstimmen und auch fehlende Spalten (fill=TRUE
) füllen kann . Ich habe dies , dies und diesen Beitrag aktualisiert . Stört es Sie, dieses zu bearbeiten, oder ist es in Ordnung, wenn ich es mache? So oder so ist gut für mich.dplyr::rbind_list
ist auch ziemlich ähnlichDurch
v1.9.2
,rbindlist
hatte ziemlich viel entwickelt, Implementierung viele Funktionen , einschließlich:Darüber hinaus in
v1.9.2
,rbind.data.table
gewinnt auch einfill
Argument, dass durch das Ausfüllen fehlende Spalt zu binden kann, implementiert in R.Jetzt
v1.9.3
gibt es noch weitere Verbesserungen an diesen vorhandenen Funktionen:rbind.data.frame
verlangsamt sich ziemlich stark, hauptsächlich aufgrund von Kopien (auf die @mnel ebenfalls hinweist), die vermieden werden könnten (indem man zu C wechselt). Ich denke, das ist nicht der einzige Grund. Die Implementierung zum Einchecken / Abgleichen von Spaltennamen inrbind.data.frame
kann auch langsamer werden, wenn viele Spalten pro data.frame vorhanden sind und viele solcher data.frames gebunden werden müssen (wie im folgenden Benchmark gezeigt).Das
rbindlist
Fehlen (ed) bestimmter Funktionen (wie das Überprüfen von Faktorstufen oder übereinstimmenden Namen) hat jedoch ein sehr geringes (oder gar kein) Gewicht dafür, dass es schneller als istrbind.data.frame
. Dies liegt daran, dass sie sorgfältig in C implementiert und auf Geschwindigkeit und Speicher optimiert wurden.Hier ist ein Maßstab, unterstreicht die effiziente Bindung , während sie durch die Spaltennamen passend als auch unter Verwendung von
rbindlist
‚s -use.names
Funktion ausv1.9.3
. Der Datensatz besteht aus 10000 Datenrahmen mit einer Größe von jeweils 10 * 500.NB: Dieser Benchmark wurde aktualisiert und enthält nun einen Vergleich mit
dplyr
'sbind_rows
Das Binden von Spalten als solche ohne Überprüfung auf Namen dauerte nur 1,3, während das Überprüfen auf Spaltennamen und das entsprechende Binden nur 1,5 Sekunden länger dauerte. Im Vergleich zur Basislösung ist dies 14x schneller und 18x schneller als
dplyr
die Version.quelle