2016-12-06 3 views
4

ich eine data.table haben wie folgtdata.table in verschachtelte Liste

## install.packages(c("gapminder", "data.table")) 
library(gapminder) 
library(data.table) 
gapminder <- data.table(gapminder) 
my_table <- gapminder[, .(mdl = .(lm(lifeExp ~ pop + gdpPercap, 
            data = gapminder))), 
          by = .(country, continent)] 

Die resultierende Tabelle wird,

   country continent mdl 
    1:  Afghanistan  Asia <lm> 
    2:   Albania Europe <lm> 
    3:   Algeria Africa <lm> 
    4:    Angola Africa <lm> 
    5:   Argentina Americas <lm> 
---         
138:   Vietnam  Asia <lm> 
139: West Bank and Gaza  Asia <lm> 
140:  Yemen, Rep.  Asia <lm> 
141:    Zambia Africa <lm> 
142:   Zimbabwe Africa <lm> 

Jetzt möchte ich aus dieser Daten eine Liste erhalten. Tabelle so, dass mdl innerhalb jedes country liegen sollte, das selbst innerhalb continent verschachtelt wird.

Ich habe versucht, wie das Ergebnis zu erhalten,

first_list <- split(my_table, my_table$continent) 
second_list <- lapply(first_list, function(x){ 
        split(x[, country := as.character(country)], x$country) 
       }) 
final_list <- sapply(second_list, function(x) sapply(x, function(y) y$mdl)) 

Gibt es eine elegante Art und Weise, dies zu tun?

+1

Sie sollten '? Split.data.table' lesen und dort auch Beispiele suchen. Die Methode 'split' data.table kann verschachtelte Listen erzeugen. Stellen Sie sicher, dass Sie aktualisieren, da 'split.data.table' in v1.9.8 eingeführt wurde. Es ist OK, SO Frage selbst zu beantworten. – jangorecki

+2

@jangorecki Bitte posten Sie eine Antwort. Ich bin neugierig, wie das geht und konnte es nicht herausfinden, nur bis zum 'Split (my_tab, by = c (" Kontinent "," Land "), keep.by = FALSE, flatten = FALSE)' wobei 'my_tab' die Tabelle ist, die so modifiziert wurde, dass sie char-Spalten anstelle von Faktoren enthält (da die letztere einen Fehler verursacht, der offensichtlich mit Spaltenbeschränkungen von' dogroups' zusammenhängt). – Frank

+0

@Frank danke für info, schau hinein – jangorecki

Antwort

1

Sie können die verschachtelte Liste haben Sie mit dieser Art von Code suchen:

res<-lapply(unique(my_table$continent), 
function(x){lapply(unique(my_table[continent==x]$country), 
function(z){my_table[continent==x&country==z]})}) 
1

können Sie die data.tree Paket verwenden:

library(data.tree) 
# create a path string 
my_table$pathString <- paste("world", my_table$continent, my_table$country, sep = "/") 

# convert the data.table to nodes and nested lists 
nested_list <- as.list(as.Node(my_table[, .(pathString, mdl)])) 

# query the result 
nested_list[["Asia"]][["Vietnam"]] 

#$mdl 
#$mdl[[1]] 

#Call: 
#lm(formula = lifeExp ~ pop + gdpPercap, data = gapminder) 

#Coefficients: 
#(Intercept)   pop gdpPercap 
# 5.365e+01 9.728e-09 7.676e-04 

Oder eine andere Option:

nested_list <- lapply(split(my_table, by = "continent"), 
         function(dt) setNames(dt$mdl, dt$country)) 

nested_list[["Asia"]][["Vietnam"]] 

#Call: 
#lm(formula = lifeExp ~ pop + gdpPercap, data = gapminder) 

#Coefficients: 
#(Intercept)   pop gdpPercap 
# 5.365e+01 9.728e-09 7.676e-04 
+1

Gibt es eine Möglichkeit, elegant die doppelte Verschachtelung '$ mdl [[1]]' zu vermeiden? – Frank

+0

@Frank. Es schien nicht vermeidbar zu sein, da die MDL-Spalte selbst Objekte ist. Wenn die Spalte ein einfacher Vektor ist, kann sie auf $ mdl reduziert werden. – Psidom