2016-12-06 82 views
4

我有一個data.table如下,data.table到嵌套表

## 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)] 

結果表會,

   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> 

現在我希望得到一個列表出這個數據的。表mdl應該位於每個country之內,其本身嵌套在continent內。

我試圖得到的結果是,

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)) 

是否有任何優雅的方式來做到這一點?

+1

你應該閱讀'?split.data.table'也檢查那裏的例子。 'split' data.table方法可以產生嵌套列表。請確保更新爲'split.data.table'在v1.9.8中引入。自我回答這個問題是可以的。 – jangorecki

+2

@jangorecki請發表一個答案。我很好奇如何做到這一點,並不能解決它,只能達到'split(my_tab,by = c(「continent」,「country」),keep.by = FALSE,flatten = FALSE)其中'my_tab'是被修改爲具有char列而不是因素的表(因爲後者拋出顯然與'dogroups'的列限制有關的錯誤)。 – Frank

+0

@Frank謝謝你的信息,將它看進去 – jangorecki

回答

1

你可以有你用這種代碼尋找嵌套列表:

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

可以使用data.tree包:

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 

或者另一種選擇:

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

有沒有一種方法可以優雅地避免使用'$ mdl [[1]]'雙重嵌套? – Frank

+0

@Frank。它似乎無法避免,因爲mdl列本身就是對象。如果該列是一個簡單的向量,則它可以簡化爲「$ mdl」。 – Psidom