glätten datensatzbasierte Liste / Objekt in Datenrahmen

8

Bearbeiten: Diese Frage ist veraltet. Das Paket jsonlite flacht automatisch ab.

Ich habe es mit Online-Datenströmen zu tun, die eine record-basierte Codierung haben, normalerweise in JSON. Die Struktur des Objekts (d. H. Die Namen in der JSON) sind aus der API-Dokumentation bekannt, Werte sind jedoch meistens optional und nicht in jedem Datensatz vorhanden. Listen können neue Listen enthalten, und die Struktur ist manchmal ziemlich tief. Hier ist ein recht einfaches Beispiel für einige GPS-Daten: Ссылка . Beachten Sie, dass in den unteren Zeilen das Objekt "l" aufgrund eines fehlenden GPS-Signals fehlt.

Ich suche nach einer eleganten Möglichkeit, diese Objekte in einen Datenrahmen zu glätten. Ich verwende derzeit so etwas:

%Vor%

Dies macht den Job, aber es ist langsam und ein wenig fehleranfällig. Ein Problem bei diesem Ansatz ist, dass ich nicht mein Wissen über die Struktur (Objektnamen) in den Daten verwende; stattdessen wird aus den Daten gefolgert. Dies führt zu Problemen, wenn eine bestimmte Eigenschaft in jedem Datensatz nicht vorhanden ist. In diesem Fall erscheint es im Datenframe überhaupt nicht anstelle einer Spalte mit NA-Werten. Dies kann zu Downstream-Problemen führen. Zum Beispiel muss ich den Ort Zeitstempel verarbeiten:

%Vor%

Dies führt jedoch zu einem Fehler im Falle eines Datensatzes, in dem das Objekt l$t nicht vorhanden ist. Außerdem machen sowohl as.data.frame als auch rbind.fill die Dinge ziemlich langsam. Der Beispieldatensatz ist relativ klein. Irgendwelche Vorschläge für eine bessere Umsetzung? Eine robuste Lösung würde immer einen Datenrahmen mit den gleichen Spalten in der gleichen Reihenfolge ergeben und nur die Anzahl der Zeilen variiert.

Bearbeiten: Unter einem Datensatz mit mehr Metadaten. Es ist größer und tiefer verschachtelt:

%Vor%     
Jeroen 25.06.2012, 20:41
quelle

3 Antworten

1

Nur aus Gründen der Klarheit füge ich eine Kombination von Josh und Joshuas Lösung hinzu, die die beste ist, auf die ich bisher gekommen bin.

%Vor%

Die Funktion ist einigermaßen schnell. Ich denke immer noch, dass es in der Lage sein sollte, dies zu beschleunigen:

%Vor%

Es erlaubt Ihnen auch, bestimmte Spalten zu "erzwingen", obwohl es nicht zu viel Beschleunigung bringt:

%Vor%     
Jeroen 26.06.2012, 22:28
quelle
5

Hier finden Sie eine Lösung, mit der Sie Ihre Vorkenntnisse in Datenfeldnamen und -klassen nutzen können. Durch die Vermeidung wiederholter Aufrufe von as.data.frame und des einzelnen Aufrufs von plyr 's rbind.fill() (beide zeitintensiv) wird es bei Ihren Beispieldaten ungefähr 60 Mal schneller ausgeführt.

%Vor%

Bearbeiten: Um zu bestätigen, dass mein Ansatz Ergebnisse liefert, die mit denen in der ursprünglichen Frage identisch sind, habe ich den folgenden Test durchgeführt. (Beachten Sie, dass ich in beiden Fällen stringsAsFactors=FALSE einstelle, um bedeutungslose Unterschiede in der Reihenfolge der Faktorstufen zu vermeiden.)

%Vor%

Weitere Bearbeitung:

Nur zur Erinnerung, hier ist eine alternative Version der obigen, die zusätzlich automatisch:

  1. findet Namen aller Datenfelder
  2. bestimmt ihre Klasse / ihren Typ
  3. erzwingt die Spalten der finalen data.frame zur korrekten Klasse

.

%Vor%     
Josh O'Brien 25.06.2012 21:16
quelle
2

Hier ist ein Versuch, der keine Annahmen über die Datentypen treffen soll. Es ist ein bisschen langsamer als @ JoshOBrien, aber schneller als die ursprüngliche Lösung des OP.

%Vor%     
Joshua Ulrich 25.06.2012 23:20
quelle

Tags und Links