Ich habe einen data.frame, den ich zeilenweise in eine Liste konvertieren möchte, was bedeutet, dass jede Zeile ihren eigenen Listenelementen entspricht. Mit anderen Worten, ich möchte eine Liste, die so lang ist, wie der data.frame Zeilen enthält.
Bisher habe ich dieses Problem folgendermaßen angegangen, aber ich habe mich gefragt, ob es einen besseren Weg gibt, dies zu erreichen.
xy.df <- data.frame(x = runif(10), y = runif(10))
# pre-allocate a list and fill it with a loop
xy.list <- vector("list", nrow(xy.df))
for (i in 1:nrow(xy.df)) {
xy.list[[i]] <- xy.df[i,]
}
split
jedes Elements Typdata.frame with 1 rows and N columns
anstelle vonlist of length N
split
Sie wahrscheinlich tun sollten,drop=T
sonst werden Ihre ursprünglichen Werte für Faktoren nicht fallenEureka!
quelle
unlist(apply(xy.df, 1, list), recursive = FALSE)
. Die Lösung von flodel ist jedoch effizienter als die Verwendung vonapply
odert
.t
dasdata.fame
in a konvertiert wird ,matrix
sodass die Elemente in Ihrer Liste Atomvektoren sind und nicht wie vom OP angefordert aufgelistet werden. Es ist normalerweise kein Problem, bis Siexy.df
gemischte Typen enthalten ...apply
. Es ist eigentlich nur eine in R implementierte for-Schleife,lapply
die die Schleife in C ausführt, was erheblich schneller ist. Dieses Zeilenlistenformat ist eigentlich vorzuziehen, wenn Sie viel schleifen.apply
Version ist.mapply(data.frame, xy.df, NULL)
Wenn Sie den data.frame (wie ich) vollständig missbrauchen und die $ -Funktionalität beibehalten möchten, können Sie Ihren data.frame in einzeilige data.frames aufteilen, die in einer Liste zusammengefasst sind:
Es ist nicht nur intellektuelle Masturbation, sondern ermöglicht es auch, den data.frame in eine Liste seiner Zeilen zu "transformieren", wobei die $ indexation beibehalten wird, die für die weitere Verwendung mit lapply nützlich sein kann (vorausgesetzt, die Funktion, die Sie an lapply übergeben, verwendet diese $ indexation).
quelle
data.frame
s in eine einzigedata.frame
verwandeln?Eine modernere Lösung verwendet nur
purrr::transpose
:quelle
Ich habe heute daran für einen data.frame (wirklich eine data.table) mit Millionen von Beobachtungen und 35 Spalten gearbeitet. Mein Ziel war es, eine Liste von data.frames (data.tables) mit jeweils einer einzelnen Zeile zurückzugeben. Das heißt, ich wollte jede Zeile in einen separaten data.frame aufteilen und diese in einer Liste speichern.
Hier sind zwei Methoden, die ich mir ausgedacht habe und die ungefähr dreimal schneller waren als
split(dat, seq_len(nrow(dat)))
für diesen Datensatz. Im Folgenden vergleiche ich die drei Methoden mit einem Datensatz mit 7500 Zeilen und 5 Spalten ( Iris 50-mal wiederholt).Dies kehrt zurück
Während die Unterschiede nicht so groß sind wie in meinem vorherigen Test, ist die gerade
setDF
Methode auf allen Ebenen der Verteilung von Läufen mit max (setDF) <min (split) signifikant schneller und dieattr
Methode ist normalerweise mehr als doppelt so schnell.Eine vierte Methode ist der extreme Champion, der einfach verschachtelt
lapply
ist und eine verschachtelte Liste zurückgibt. Diese Methode veranschaulicht die Kosten für die Erstellung eines data.frame aus einer Liste. Außerdem waren alle Methoden, die ich mit derdata.frame
Funktion ausprobierte, ungefähr eine Größenordnung langsamer als diedata.table
Techniken.Daten
quelle
Eine aktuelle Version des
purrr
Pakets (0.2.2) scheint die schnellste Lösung zu sein:Vergleichen wir die interessantesten Lösungen:
Ergebnisse:
Das gleiche Ergebnis erzielen wir auch mit
Rcpp
:Vergleichen Sie jetzt mit
purrr
:Ergebnisse:
quelle
by_row()
ist jetzt umgezogen zulibrary(purrrlyr)
Ein paar weitere Optionen:
Mit
asplit
Mit
split
undrow
Daten
quelle
Der beste Weg für mich war:
Beispieldaten:
Wir rufen die
BBmisc
Bibliothek anUnd das Ergebnis wird sein:
quelle
Eine alternative Möglichkeit besteht darin, den df in eine Matrix umzuwandeln und dann die Listenanwendungsfunktion darauf anzuwenden
lappy
:ldf <- lapply(as.matrix(myDF), function(x)x)
quelle
Eine andere Alternative
library(purrr)
(die bei großen Datenmengen etwas schneller zu sein scheint).quelle
Wie @flodel schrieb: Dies konvertiert Ihren Datenrahmen in eine Liste, die die gleiche Anzahl von Elementen wie die Anzahl der Zeilen im Datenrahmen enthält:
Sie können zusätzlich eine Funktion hinzufügen, um nur die Spalten auszuwählen, die nicht NA in jedem Element der Liste sind:
quelle
Die
by_row
Funktion aus dempurrrlyr
Paket erledigt dies für Sie.Dieses Beispiel zeigt
Standardmäßig wird der zurückgegebene Wert von
myfn
in eine neue Listenspalte in der aufgerufenen df eingefügt.out
. Am$.out
Ende der obigen Anweisung wird diese Spalte sofort ausgewählt und eine Liste mit Listen zurückgegeben.quelle