r - R:展平列表列表的内部部分,同时保持其结构
问题描述
我正在进行一项模拟研究,我的结果存储在嵌套列表结构中。列表的第一级代表模型生成的不同超参数。第二个层次是同一模型的复制次数(改变种子)。
在下面的示例中,我列出了由两个超参数(hyperpar1 和 hyperpar2)控制的模型的输出,其中两个超参数都可以采用 2 个不同的值,从而导致生成的模型有 4 种不同的组合。此外,4 种可能的组合中的每一种都运行了两次(不同的种子),产生了 8 种可能的组合(如下所示str(res, max = 2)
)。最后,从模型的每个可能迭代(metric1 和 metric2)以及模型的两个参数的值中恢复了两个性能指标beta = list(b1 = value, b2 = value)
。
我的问题与最后一部分有关。我想展平列表beta
并将列表中的每个组件作为包含它的上列表的组件,但保持开头描述的整个结构不变。
下面是一个例子:
数据样本。
res <-list(
list(list(modeltype = "tree", time_iter = structure(0.7099, class = "difftime", units = "secs"),seed = 1, nobs = 75, hyperpar1 = 0.5, hyperpar2 = 0.5, metric1 = 0.4847, metric2 = 0.2576, beta = list(b1 = 0.575, b2 =0.745)),
list(modeltype = "tree", time_iter = structure(0.058 , class = "difftime", units = "secs"),seed = 2, nobs = 75, hyperpar1 = 0.5, hyperpar2 = 0.5, metric1 = 0.4013, metric2 = 0.2569, beta = list(b1 = 0.535, b2 =0.775))),
list(list(modeltype = "tree", time_iter = structure(0.046 , class = "difftime", units = "secs"),seed = 1, nobs = 75, hyperpar1 = 0.8, hyperpar2 = 0.5, metric1 = 0.4755, metric2 = 0.2988, beta = list(b1 = 0.541, b2 =0.702) ),
list(modeltype = "tree", time_iter = structure(0.0474, class = "difftime", units = "secs"),seed = 2, nobs = 75, hyperpar1 = 0.8, hyperpar2 = 0.5, metric1 = 0.2413, metric2 = 0.2147, beta = list(b1 = 0.545, b2 =0.793) )),
list(list(modeltype = "tree", time_iter = structure(0.0502, class = "difftime", units = "secs"),seed = 1, nobs = 75, hyperpar1 = 0.5, hyperpar2 = 1 , metric1 = 0.7131, metric2 = 0.5024, beta = list(b1 = 0.500, b2 =0.722) ),
list(modeltype = "tree", time_iter = structure(2.9419, class = "difftime", units = "secs"),seed = 2, nobs = 75, hyperpar1 = 0.5, hyperpar2 = 1 , metric1 = 0.4254, metric2 = 0.2824, beta = list(b1 = 0.555, b2 =0.712) )),
list(list(modeltype = "tree", time_iter = structure(0.041 , class = "difftime", units = "secs"),seed = 1, nobs = 75, hyperpar1 = 0.8, hyperpar2 = 1 , metric1 = 0.6709, metric2 = 0.4092, beta = list(b1 = 0.578, b2 =0.701) ),
list(modeltype = "tree", time_iter = structure(0.0396, class = "difftime", units = "secs"),seed = 2, nobs = 75, hyperpar1 = 0.8, hyperpar2 = 1 , metric1 = 0.4585, metric2 = 0.4115, beta = list(b1 = 0.501, b2 =0.777) )))
获得的输出的插图。
str(res[[1]][[1]], max = 3)
# List of 9
# $ modeltype: chr "tree"
# $ time_iter: 'difftime' num 0.7099
# ..- attr(*, "units")= chr "secs"
# $ seed : num 1
# $ nobs : num 75
# $ hyperpar1: num 0.5
# $ hyperpar2: num 0.5
# $ metric1 : num 0.485
# $ metric2 : num 0.258
# $ beta :List of 2 #### <----- ( here is what I want to flatten/unlist )
# ..$ b1: num 0.575
# ..$ b2: num 0.745
期望的输出(betas flattened)
str(res[[1]][[1]], max = 3)
# List of 9
# $ modeltype: chr "tree"
# $ time_iter: 'difftime' num 0.7099
# ..- attr(*, "units")= chr "secs"
# $ seed : num 1
# $ nobs : num 75
# $ hyperpar1: num 0.5
# $ hyperpar2: num 0.5
# $ metric1 : num 0.485
# $ metric2 : num 0.258
# $ b1: num 0.575 #### <----- ( here is new because )
# $ b2: num 0.745 #### <----- ( this part is flat now! )
PS:附带说明一下,模拟需要几天时间才能完成,而且并非所有模型中的参数数量都是恒定的;这就是为什么我想展平列表,beta
不管它里面是什么。欢迎打包解决方案(例如,.data.table
或dplyr
)。谢谢。
解决方案
我不确定这是否适用于真实数据,但它似乎产生了对上面示例数据的渴望。
map_depth(res, 2, flatten)
这是完整的输出str
:
library(purrr)
map_depth(res, 2, flatten) %>% str
#> List of 4
#> $ :List of 2
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: num 0.71
#> .. ..$ seed : num 1
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.5
#> .. ..$ hyperpar2: num 0.5
#> .. ..$ metric1 : num 0.485
#> .. ..$ metric2 : num 0.258
#> .. ..$ b1 : num 0.575
#> .. ..$ b2 : num 0.745
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: num 0.058
#> .. ..$ seed : num 2
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.5
#> .. ..$ hyperpar2: num 0.5
#> .. ..$ metric1 : num 0.401
#> .. ..$ metric2 : num 0.257
#> .. ..$ b1 : num 0.535
#> .. ..$ b2 : num 0.775
#> $ :List of 2
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: num 0.046
#> .. ..$ seed : num 1
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.8
#> .. ..$ hyperpar2: num 0.5
#> .. ..$ metric1 : num 0.475
#> .. ..$ metric2 : num 0.299
#> .. ..$ b1 : num 0.541
#> .. ..$ b2 : num 0.702
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: num 0.0474
#> .. ..$ seed : num 2
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.8
#> .. ..$ hyperpar2: num 0.5
#> .. ..$ metric1 : num 0.241
#> .. ..$ metric2 : num 0.215
#> .. ..$ b1 : num 0.545
#> .. ..$ b2 : num 0.793
#> $ :List of 2
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: num 0.0502
#> .. ..$ seed : num 1
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.5
#> .. ..$ hyperpar2: num 1
#> .. ..$ metric1 : num 0.713
#> .. ..$ metric2 : num 0.502
#> .. ..$ b1 : num 0.5
#> .. ..$ b2 : num 0.722
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: num 2.94
#> .. ..$ seed : num 2
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.5
#> .. ..$ hyperpar2: num 1
#> .. ..$ metric1 : num 0.425
#> .. ..$ metric2 : num 0.282
#> .. ..$ b1 : num 0.555
#> .. ..$ b2 : num 0.712
#> $ :List of 2
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: num 0.041
#> .. ..$ seed : num 1
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.8
#> .. ..$ hyperpar2: num 1
#> .. ..$ metric1 : num 0.671
#> .. ..$ metric2 : num 0.409
#> .. ..$ b1 : num 0.578
#> .. ..$ b2 : num 0.701
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: num 0.0396
#> .. ..$ seed : num 2
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.8
#> .. ..$ hyperpar2: num 1
#> .. ..$ metric1 : num 0.459
#> .. ..$ metric2 : num 0.411
#> .. ..$ b1 : num 0.501
#> .. ..$ b2 : num 0.777
由reprex 包于 2021-02-21 创建(v0.3.0)
更新
上述方法的问题是所有其他变量都转换为numeric
,这是不可取的,因为time_iter
它最初是一个difftime
对象。
下面的方法更详细,但不会将其他变量转换为numeric
:
res %>%
map(
~ modify(.x, function(x) {
x <- append(x, unlist(x$beta))
x$beta <- NULL
x
})
下面是输出str
:
res %>%
map(
~ modify(.x, function(x) {
x <- append(x, unlist(x$beta))
x$beta <- NULL
x
})
) %>% str
#> List of 4
#> $ :List of 2
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: 'difftime' num 0.7099
#> .. .. ..- attr(*, "units")= chr "secs"
#> .. ..$ seed : num 1
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.5
#> .. ..$ hyperpar2: num 0.5
#> .. ..$ metric1 : num 0.485
#> .. ..$ metric2 : num 0.258
#> .. ..$ b1 : num 0.575
#> .. ..$ b2 : num 0.745
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: 'difftime' num 0.058
#> .. .. ..- attr(*, "units")= chr "secs"
#> .. ..$ seed : num 2
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.5
#> .. ..$ hyperpar2: num 0.5
#> .. ..$ metric1 : num 0.401
#> .. ..$ metric2 : num 0.257
#> .. ..$ b1 : num 0.535
#> .. ..$ b2 : num 0.775
#> $ :List of 2
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: 'difftime' num 0.046
#> .. .. ..- attr(*, "units")= chr "secs"
#> .. ..$ seed : num 1
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.8
#> .. ..$ hyperpar2: num 0.5
#> .. ..$ metric1 : num 0.475
#> .. ..$ metric2 : num 0.299
#> .. ..$ b1 : num 0.541
#> .. ..$ b2 : num 0.702
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: 'difftime' num 0.0474
#> .. .. ..- attr(*, "units")= chr "secs"
#> .. ..$ seed : num 2
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.8
#> .. ..$ hyperpar2: num 0.5
#> .. ..$ metric1 : num 0.241
#> .. ..$ metric2 : num 0.215
#> .. ..$ b1 : num 0.545
#> .. ..$ b2 : num 0.793
#> $ :List of 2
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: 'difftime' num 0.0502
#> .. .. ..- attr(*, "units")= chr "secs"
#> .. ..$ seed : num 1
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.5
#> .. ..$ hyperpar2: num 1
#> .. ..$ metric1 : num 0.713
#> .. ..$ metric2 : num 0.502
#> .. ..$ b1 : num 0.5
#> .. ..$ b2 : num 0.722
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: 'difftime' num 2.9419
#> .. .. ..- attr(*, "units")= chr "secs"
#> .. ..$ seed : num 2
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.5
#> .. ..$ hyperpar2: num 1
#> .. ..$ metric1 : num 0.425
#> .. ..$ metric2 : num 0.282
#> .. ..$ b1 : num 0.555
#> .. ..$ b2 : num 0.712
#> $ :List of 2
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: 'difftime' num 0.041
#> .. .. ..- attr(*, "units")= chr "secs"
#> .. ..$ seed : num 1
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.8
#> .. ..$ hyperpar2: num 1
#> .. ..$ metric1 : num 0.671
#> .. ..$ metric2 : num 0.409
#> .. ..$ b1 : num 0.578
#> .. ..$ b2 : num 0.701
#> ..$ :List of 10
#> .. ..$ modeltype: chr "tree"
#> .. ..$ time_iter: 'difftime' num 0.0396
#> .. .. ..- attr(*, "units")= chr "secs"
#> .. ..$ seed : num 2
#> .. ..$ nobs : num 75
#> .. ..$ hyperpar1: num 0.8
#> .. ..$ hyperpar2: num 1
#> .. ..$ metric1 : num 0.459
#> .. ..$ metric2 : num 0.411
#> .. ..$ b1 : num 0.501
#> .. ..$ b2 : num 0.777
由reprex 包于 2021-03-27 创建(v0.3.0)
推荐阅读
- python - Django上传后获取整个文件路径
- r - R:如何通过列名将列分配给矩阵
- c# - 在实体框架中添加复杂对象
- html - 如何将图像添加到 github 网站上的导航栏
- javascript - 客户端控制台错误“Uncaught SyntaxError: Unexpected token '<'”
- r - R:合并日期范围内的两个数据集
- typescript - 打字稿,无法处理缺失属性的联合。[tsserver 2339] 类型上不存在属性“数据”
- python - 找出哪个迭代函数得到最大值?
- windows - 在 Windows 上没有可执行文件的情况下如何执行服务?
- python - How to use Axios/Vue.js to call data from SQLite/Django backend?