R:在保持列表结构的同时,将列表的内部部分扁平化

4sup72z8  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(110)

我正在运行一个模拟研究,结果存储在嵌套列表结构中。列表的第一级表示模型生成的不同超参数。第二级是同一模型的重复次数(更改种子)。
在下例中,我列出了由两个超参数控制的模型的输出(hyperpar 1和hyperpar 2),其中两者都可以取2个不同的值,从而导致生成的模型有4种不同的组合。此外,4种可能的组合中的每一种都运行了两次(不同的种子),导致八种可能的组合(如下面str(res, max = 2)所示)。最后,从模型的每个可能迭代中恢复两个性能度量(度量1和度量2),并且还恢复模型的两个参数的值X1 M1 N1 X。
我的问题与最后一部分有关,我想将列表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

所需输出(Beta平坦)

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

附言:作为一个侧记,模拟需要几天的时间才能完成,并不是所有的时间参数的数量是恒定的模型;这就是为什么我想把beta列表扁平化,不管它里面是什么。2打包的解决方案是受欢迎的(例如,. data.tabledplyr)。3谢谢。

z9gpfhce

z9gpfhce1#

我不确定这是否适用于真实的数据,但它似乎产生了对上面示例数据的渴望。
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 package(v0.3.0)于2021年2月21日创建

更新

上述方法的问题是所有其他变量都被转换为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 package(v0.3.0)于2021年3月27日创建

x3naxklr

x3naxklr2#

这个管用

res2 <- map_depth(res, 2, ~ list_flatten(., name_spec = "{inner}"))

str(res2)
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

相关问题