643 Stimmen

Eine Liste in ein Datenrahmen konvertieren

Ich habe eine verschachtelte Liste von Daten. Ihre Länge beträgt 132 und jedes Element ist eine Liste von Länge 20. Gibt es einen schnellen Weg, diese Struktur in ein Datenrahmen umzuwandeln, der 132 Zeilen und 20 Spalten Daten hat?

Hier sind einige Beispieldaten, mit denen gearbeitet werden kann:

l <- replicate(
  132,
  as.list(sample(letters, 20)),
  simplify = FALSE
)

2 Stimmen

Möchten Sie also jedes Listen-Element als eine Datendefinition in Ihrem Dataframe haben?

2 Stimmen

@RichieCotton Es ist kein richtiges Beispiel. "jedes Element ist eine Liste der Länge 20" und du hast jedes Element ist eine Liste eines Vektors der Länge 20.

1 Stimmen

Spät zur Party, aber ich habe niemanden erwähnen sehen dies, das ich für sehr praktisch hielt (für das, was ich vorhatte).

621voto

Marek Punkte 47395

Mit rbind

do.call(rbind.data.frame, your_list)

Bearbeiten: Die vorherige Version gibt data.frame von list's zurück, anstatt Vektoren (wie @IanSudbery in den Kommentaren angemerkt hat).

8 Stimmen

Warum funktioniert dies, aber rbind(your_list) gibt eine 1x32-Listenmatrix zurück?

36 Stimmen

@eykanal do.call gibt die Elemente von your_list als Argumente an rbind weiter. Es entspricht rbind(your_list[[1]], your_list[[2]], your_list[[3]], ....., your_list[[Länge von your_list]]).

2 Stimmen

Diese Methode leidet unter der Null-Situation.

481voto

nico Punkte 49590

Aktualisierung Juli 2020:

Der Standard für den Parameter stringsAsFactors ist jetzt default.stringsAsFactors(), was wiederum FALSE als Standard liefert.


Angenommen, Ihre Liste von Listen heißt l:

df <- data.frame(matrix(unlist(l), nrow=length(l), byrow=TRUE))

Das obige Beispiel wandelt alle Zeichenspalten in Faktoren um. Um dies zu vermeiden, können Sie einen Parameter zum data.frame() Aufruf hinzufügen:

df <- data.frame(matrix(unlist(l), nrow=132, byrow=TRUE),stringsAsFactors=FALSE)

132 Stimmen

Vorsicht hier, wenn Ihre Daten nicht alle vom gleichen Typ sind. Das Durchlaufen einer Matrix bedeutet, dass alle Daten in einen gemeinsamen Typ gezwungen werden. d.h. Wenn Sie eine Spalte mit Zeichendaten und eine Spalte mit numerischen Daten haben, werden die numerischen Daten von matrix() in einen String umgewandelt und dann von data.frame() beide zu Faktoren.

1 Stimmen

Was ist der beste Weg, dies zu tun, wenn die Liste fehlende Werte aufweist oder um NA in den Datenrahmen aufzunehmen?

0 Stimmen

@Dave: Ich glaube, ich verstehe dich nicht ganz... das funktioniert auch, wenn es NAs gibt...

166voto

mropa Punkte 10904

Sie können das plyr-Paket verwenden. Zum Beispiel eine verschachtelte Liste der Form

l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
      , b = list(var.1 = 4, var.2 = 5, var.3 = 6)
      , c = list(var.1 = 7, var.2 = 8, var.3 = 9)
      , d = list(var.1 = 10, var.2 = 11, var.3 = 12)
      )

hat jetzt eine Länge von 4 und jede Liste in l enthält eine weitere Liste der Länge 3. Jetzt können Sie ausführen

library (plyr)
  df <- ldply (l, data.frame)

und sollten das gleiche Ergebnis wie in der Antwort von @Marek und @nico erhalten.

8 Stimmen

Tolle Antwort. Könntest du ein wenig erklären, wie das funktioniert? Gibt es einfach ein Datenrahmen für jeden Listeneintrag zurück?

14 Stimmen

Imho die BESTE Antwort. Es gibt ein ehrliches data.frame zurück. Alle Datentypen (Zeichenfolge, Zahl usw.) werden korrekt transformiert. Wenn die Liste verschiedene Datentypen enthält, werden sie alle mit dem matrix-Ansatz in Zeichenfolgen transformiert.

1 Stimmen

Der hier bereitgestellte Muster ist nicht der vom Fragesteller bereitgestellte. Das Ergebnis dieser Antwort auf dem Originaldatensatz ist falsch.

136voto

Alex Brown Punkte 40146

Die Musterdaten werden so angepasst, dass sie der ursprünglichen Beschreibung "jedes Element ist eine Liste der Länge 20" entsprechen

mylistlist <- replicate(
  132,
  as.list(sample(letters, 20)),
  simplify = FALSE
)

Wir können es wie folgt in ein Datenrahmen umwandeln:

data.frame(t(sapply(mylistlist,c)))

sapply konvertiert es in eine Matrix. data.frame konvertiert die Matrix in einen Datenrahmen.

Ergebnis:

Bildbeschreibung hier eingeben

22 Stimmen

Beste Antwort weit und breit! Keine der anderen Lösungen bekommt die Typen/Spaltennamen richtig. DANKE!

2 Stimmen

Welche Rolle beabsichtigen Sie c hier zu spielen, eine Instanz der Listen-Daten? Oh warte, c für die Verknüpfungsfunktion, richtig? Ich werde verwirrt über @mnel's Verwendung von c. Ich stimme auch mit @dchandler überein, die korrekten Spaltennamen zu bekommen war ein wertvolles Bedürfnis in meinem Anwendungsfall. Brillante Lösung.

0 Stimmen

Das ist richtig - Standard-c-Funktion; aus ?c : Werte zu einem Vektor oder einer Liste kombinieren

89voto

jdeng Punkte 2774

Angenommen, Ihre Liste heißt L,

data.frame(Reduce(rbind, L))

2 Stimmen

Schöne Arbeit! Es gibt einen Unterschied bei der Lösung von @Alex Brown im Vergleich zu Ihrer, bei der Ihr Weg aus irgendeinem Grund die folgende Warnmeldung erzeugte: `Warnmeldung: Bei data.row.names(row.names, rowsi, i) : einige row.names doppelt vorhanden: 3,4 --> row.names NICHT verwendet'

0 Stimmen

Sehr gut!! Hat bei mir hier funktioniert: stackoverflow.com/questions/32996321/…

3 Stimmen

Funktioniert gut, es sei denn, die Liste enthält nur ein Element: data.frame(Reduce(rbind, list(c('col1','col2')))) liefert ein Datenrahmen mit 2 Zeilen, 1 Spalte (ich erwartete 1 Zeile, 2 Spalten)

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