将data.table转换为嵌套列表

4

我有一个如下所示的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 应该位于每个嵌套在 continent 中的 country 内。
我尝试了以下方法来获得结果:
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数据表方法可以生成嵌套列表。请确保更新到v1.9.8中引入的split.data.table。自我回答SO问题是可以的。 - jangorecki
2
@jangorecki 请发表一个答案。我很好奇如何做到这一点,但是无法弄清楚,只能到达 split(my_tab, by=c("continent", "country"), keep.by = FALSE, flatten = FALSE) 这一步,其中 my_tab 是修改为字符列而不是因子的表格(因为后者会引发与 dogroups 列限制相关的错误)。 - Frank
@Frank 谢谢你的信息,我会去了解一下。 - jangorecki
相关链接:https://dev59.com/FJffa4cB1Zd3GeqP4zzi/ - Frank
1
@Frank,我已经填写了#1954,在转换为字符过程中运行良好。 - jangorecki
2个回答

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
@Frank。看起来无法避免,因为mdl列本身就是对象。如果该列仅仅是一个向量,那么可以简化为“$mdl”。 - Psidom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接