Ich habe eine verschachtelte Liste von Daten. Seine Länge beträgt 132 und jedes Element ist eine Liste der Länge 20. Gibt es eine schnelle Möglichkeit, diese Struktur in einen Datenrahmen mit 132 Zeilen und 20 Datenspalten zu konvertieren?
Hier sind einige Beispieldaten, mit denen Sie arbeiten können:
l <- replicate(
132,
list(sample(letters, 20)),
simplify = FALSE
)
Antworten:
Angenommen, Ihre Liste der Listen heißt
l
:Mit dem obigen Befehl werden alle Zeichenspalten in Faktoren konvertiert. Um dies zu vermeiden, können Sie dem Aufruf von data.frame () einen Parameter hinzufügen:
quelle
Mit
rbind
Bearbeiten: Vorherige Version Rückgabe
data.frame
vonlist
's anstelle von Vektoren (wie @IanSudbery in Kommentaren hervorhob).quelle
rbind(your_list)
gibt aber eine 1x32-Listenmatrix zurück?do.call
Elementeyour_list
als Argumente an übergebenrbind
. Es ist gleichbedeutend mitrbind(your_list[[1]], your_list[[2]], your_list[[3]], ....., your_list[[length of your_list]])
.your_list
gleich große Vektoren enthalten sind.NULL
hat die Länge 0, sollte also fehlschlagen.Sie können das
plyr
Paket verwenden. Zum Beispiel eine verschachtelte Liste des Formularshat jetzt eine Länge von 4 und jede Liste in
l
enthält eine andere Liste der Länge 3. Jetzt können Sie ausführenund sollte das gleiche Ergebnis wie in der Antwort @Marek und @nico erhalten.
quelle
matrix
Annäherung in Zeichen umgewandelt .data.frame(t(sapply(mylistlist,c)))
sapply
konvertiert es in eine Matrix.data.frame
konvertiert die Matrix in einen Datenrahmen.quelle
c
hier spielen, eine Instanz der Listendaten? Oh warte, c auf die Verkettungsfunktion, oder? Verwechseln mit der Verwendung von c durch @ mnel. Ich stimme auch @dchandler zu, die richtigen Spaltennamen zu finden, war in meinem Anwendungsfall ein wertvolles Bedürfnis. Geniale Lösung.?c
:Combine Values into a Vector or List
Angenommen, Ihre Liste heißt
L
,quelle
data.frame(Reduce(rbind, list(c('col1','col2'))))
Erzeugt einen Datenrahmen mit 2 Zeilen, 1 Spalte (ich habe 1 Zeile 2 Spalten erwartet)Das Paket
data.table
hat die Funktion,rbindlist
die eine superschnelle Implementierung von istdo.call(rbind, list(...))
.Es kann dauern eine Liste
lists
,data.frames
oderdata.tables
als Eingabe.Dies gibt ein
data.table
Erbe von zurückdata.frame
.Wenn Sie wirklich wieder in einen data.frame konvertieren möchten, verwenden Sie
as.data.frame(DT)
quelle
setDF
jetzt als Referenz zu data.frame zurückkehren.Das
tibble
Paket verfügt über eine Funktionenframe()
, die dieses Problem löst, indem verschachteltelist
Objekte zu verschachtelten Objektentibble
("aufgeräumten" Datenrahmen) gezwungen werden. Hier ist ein kurzes Beispiel von R for Data Science :Da Ihre Liste mehrere Nester enthält,
l
können Sie mithilfe derunlist(recursive = FALSE)
Option unnötige Verschachtelungen entfernen, um nur eine einzige hierarchische Liste abzurufen und anschließend an zu übergebenenframe()
. Ich verwendetidyr::unnest()
, um die Ausgabe in einen einstufigen "aufgeräumten" Datenrahmen zu entstören, der Ihre zwei Spalten enthält (eine für die Gruppename
und eine für die Beobachtungen mit den Gruppenvalue
). Wenn Sie Spalten wünschen, die breit werden, können Sie eine Spalte hinzufügen, indem Sieadd_column()
die Reihenfolge der Werte 132 Mal wiederholen. Dann nur nochspread()
die Werte.quelle
Abhängig von der Struktur Ihrer Listen gibt es einige
tidyverse
Optionen, die bei Listen mit ungleicher Länge gut funktionieren:Sie können auch Vektoren und Datenrahmen mischen:
quelle
X2
kann nicht von Ganzzahl in Zeichen konvertiert werdenReshape2 liefert die gleiche Ausgabe wie das obige Plyr-Beispiel:
Ausbeuten:
Wenn Sie fast keine Pixel mehr haben, können Sie dies alles in einer Zeile mit recast () tun.
quelle
Diese Methode verwendet ein
tidyverse
Paket ( purrr ).Die Liste:
Konvertieren in einen Datenrahmen (
tibble
genauer gesagt):quelle
Erweitern Sie die Antwort von @ Marek: Wenn Sie vermeiden möchten, dass Zeichenfolgen in Faktoren umgewandelt werden, ist Effizienz kein Problem
quelle
Für den allgemeinen Fall tief verschachtelter Listen mit 3 oder mehr Ebenen, wie sie von einem verschachtelten JSON erhalten wurden:
Betrachten Sie zunächst den Ansatz
melt()
, die verschachtelte Liste in ein großes Format zu konvertieren:gefolgt von
dcast()
dann zu breit in einen ordentlichen Datensatz, in dem jede Variable eine Spalte und jede Beobachtung eine Zeile bildet:quelle
Weitere Antworten sowie Zeitangaben in der Antwort auf diese Frage: Wie lässt sich eine Liste am effizientesten als Datenrahmen umwandeln?
Der schnellste Weg, der keinen Datenrahmen mit Listen anstelle von Vektoren für Spalten erzeugt, scheint zu sein (aus Martin Morgans Antwort):
quelle
Manchmal können Ihre Daten eine Liste von Listen von Vektoren gleicher Länge sein.
(Die inneren Vektoren könnten auch Listen sein, aber ich vereinfache, um dies leichter lesbar zu machen).
Dann können Sie die folgende Änderung vornehmen. Denken Sie daran, dass Sie jeweils eine Ebene aufheben können:
Verwenden Sie nun Ihre in den anderen Antworten erwähnte Lieblingsmethode:
quelle
Das hat endlich bei mir funktioniert:
do.call("rbind", lapply(S1, as.data.frame))
quelle
quelle
Verwenden Sie für eine parallele Lösung (Multicore, Multisession usw.) unter Verwendung
purrr
einer Lösungsfamilie:Wo
l
ist die Liste?Um das effizienteste Benchmarking durchzuführen
plan()
, können Sie Folgendes verwenden:quelle
Der folgende einfache Befehl hat bei mir funktioniert:
Referenz ( Quora Antwort )
Dies schlägt jedoch fehl, wenn nicht klar ist, wie die Liste in einen Datenrahmen konvertiert werden soll:
Hinweis : Die Antwort bezieht sich auf den Titel der Frage und überspringt möglicherweise einige Details der Frage
quelle
Ein kurzer (aber vielleicht nicht der schnellste) Weg, dies zu tun, wäre die Verwendung der Basis r, da ein Datenrahmen nur eine Liste von Vektoren gleicher Länge ist . Die Konvertierung zwischen Ihrer Eingabeliste und einem 30 x 132-Datenrahmen wäre also:
Von dort aus können wir es in eine 132 x 30-Matrix transponieren und wieder in einen Datenrahmen konvertieren:
Als Einzeiler:
Die Rownamen sind ziemlich nervig anzusehen, aber Sie können sie jederzeit mit umbenennen
rownames(new_df) <- 1:nrow(new_df)
quelle
Wie wäre es mit der
map_
Funktion zusammen mit einerfor
Schleife? Hier ist meine Lösung:Dabei
map_dfr
konvertieren Sie jedes Listenelement in einen data.frame und vereinen Sie sie dannrbind
insgesamt.In Ihrem Fall wäre es wohl:
quelle