2013-03-04 21 views
6

Ich habe einen Datenrahmen, den ich in eine verschachtelte Liste mit einer benutzerdefinierten Verschachtelungsebene konvertieren möchte. Dies ist, wie ich es tun, aber ich bin sicher, es gibt einen besseren Weg:Wie konvertiert man einen Datenrahmen in eine verschachtelte Liste?

data <- data.frame(city=c("A", "A", "B", "B"), street=c("a", "b", "a", "b"), tenant=c("Smith","Jones","Smith","Jones"), income=c(100,200,300,400)) 

nested_data <- lapply(levels(data$city), function(city){ 
    data_city <- subset(data[data$city == city, ], select=-city) 
    list(city = city, street_values=lapply(levels(data_city$street), function(street){ 
     data_city_street <- subset(data_city[data_city$street == street, ], select=-street) 
     tenant_values <- apply(data_city_street, 1, function(income_tenant){ 
      income_tenant <- as.list(income_tenant) 
      list(tenant=income_tenant$tenant, income=income_tenant$income) 
     }) 
     names(tenant_values) <- NULL 
     list(street=street, tenant_values=tenant_values) 
    })) 
}) 

Die Ausgabe in JSON wie folgt aussieht:

library(rjson) 
write(toJSON(nested_data), "") 
[{"city":"A","street_values":[{"street":"a","tenant_values":[{"tenant":"Smith","income":"100"}]},{"street":"b","tenant_values":[{"tenant":"Jones","income":"200"}]}]},{"city":"B","street_values":[{"street":"a","tenant_values":[{"tenant":"Smith","income":"300"}]},{"street":"b","tenant_values":[{"tenant":"Jones","income":"400"}]}]}] 

# or prettified: 

[ 
    { 
    "city": "A", 
    "street_values": [ 
     { 
     "street": "a", 
     "tenant_values": [ 
      { 
      "tenant": "Smith", 
      "income": "100" 
      } 
     ] 
     }, 
     { 
     "street": "b", 
     "tenant_values": [ 
      { 
      "tenant": "Jones", 
      "income": "200" 
      } 
     ] 
     } 
    ] 
    }, 
    { 
    "city": "B", 
    "street_values": [ 
     { 
     "street": "a", 
     "tenant_values": [ 
      { 
      "tenant": "Smith", 
      "income": "300" 
      } 
     ] 
     }, 
     { 
     "street": "b", 
     "tenant_values": [ 
      { 
      "tenant": "Jones", 
      "income": "400" 
      } 
     ] 
     } 
    ] 
    } 
] 

Gibt es einen besseren Weg, dies zu tun?

+0

, sind Sie eine Frage zu 'JSON' Ausgabe von R zu fragen, oder wie ein' R' Objekt zu schaffen, die eine ist "verschachtelte Liste" in R-Definition, z 'foo <-list (bar = NA, snafu =" Hallo, Dave "); foo [[bar]] <- Liste (a = 1, b = 2) '? –

+0

Ich habe gerade die 'JSON'-Ausgabe gezeigt, weil sie einfacher zu verstehen ist als das R-Listenformat, aber ich möchte von R-Datenformat in R-Liste wechseln – nachocab

Antwort

8

Was split über die Verwendung von Ihnen die meisten der Art und Weise, und rapply für den letzten Schritt zu erhalten:

nestedList <- rapply(lapply(split(data[-1], data[1]), 
          function(x) split(x[-1], x[1])), 
        f = function(x) as.character(unlist(x)), 
        how = "replace") 

Hier ist der Ausgang:

nestedList 
# $A 
# $A$a 
# $A$a$tenant 
# [1] "Smith" 
# 
# $A$a$income 
# [1] "100" 
# 
# 
# $A$b 
# $A$b$tenant 
# [1] "Jones" 
# 
# $A$b$income 
# [1] "200" 
# 
# 
# 
# $B 
# $B$a 
# $B$a$tenant 
# [1] "Smith" 
# 
# $B$a$income 
# [1] "300" 
# 
# 
# $B$b 
# $B$b$tenant 
# [1] "Jones" 
# 
# $B$b$income 
# [1] "400" 

und die Struktur:

> str(nestedList) 
List of 2 
$ A:List of 2 
    ..$ a:List of 2 
    .. ..$ tenant: chr "Smith" 
    .. ..$ income: chr "100" 
    ..$ b:List of 2 
    .. ..$ tenant: chr "Jones" 
    .. ..$ income: chr "200" 
$ B:List of 2 
    ..$ a:List of 2 
    .. ..$ tenant: chr "Smith" 
    .. ..$ income: chr "300" 
    ..$ b:List of 2 
    .. ..$ tenant: chr "Jones" 
    .. ..$ income: chr "400" 

Die Struktur stimmt nicht genau mit dem überein, was Sie suchen, aber das könnte helfen Beginne mit einem alternativen Ansatz.

1

fand ich die Lösung meiner Frage durch die Funktion als Wechsel: So

nestedList <- rapply(lapply(split(df[-1], df[1]), 
          function(x) split(x[-1], x[1])), 
        f = function(x) as.data.frame(as.list(split(x,x))), how = "replace") 
Verwandte Themen