根据条件展平 R 中的列表

Flatten a list in R based on conditions

我想弄清楚如何根据特定条件展平嵌套列表。这是一个示例列表 -

example_list <- list(list1 = list(data = mtcars, char = c("a","b")),
                     num = c(1:3),
                     mat = matrix(1:10),
                     list2 = list(c = "c",d = "d"),
                     list3 = list(1, 2))  

如果 (1) 元素的 class 不是数据,或者 (2) 如果元素的名称不是 "清单 2”。因此,展平列表应包含这些元素 - data、char、num、mat、list2、1、2。

预期的输出应该是 -

output <- list(data = mtcars, 
               char = c("a","b"),
               num = c(1:3),
               mat = matrix(1:10),
               list2 = list(c = "c", d = "d"),
               1,2)

P.S.: 如果这个问题有一个基于rrapply的解决方案就好了。

谢谢!

假设 example_list 中的 list1list2 应该交换,使用 rrapply() 我们可以这样做:

## flatten list based on condition(s)
output <- rrapply(
  example_list,
  how = "flatten",
  classes = c("list", "ANY"),
  condition = function(x, .xname) .xname == "list1" || is.data.frame(x) || is.character(x) || is.numeric(x),
)

str(output, list.len = 7)

#> List of 7
#>  $ data :'data.frame':   32 obs. of  11 variables:
#>   ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
#>   ..$ cyl : num [1:32] 6 6 4 6 8 6 8 4 4 6 ...
#>   ..$ disp: num [1:32] 160 160 108 258 360 ...
#>   ..$ hp  : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
#>   ..$ drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
#>   ..$ wt  : num [1:32] 2.62 2.88 2.32 3.21 3.44 ...
#>   ..$ qsec: num [1:32] 16.5 17 18.6 19.4 17 ...
#>   .. [list output truncated]
#>  $ char : chr [1:2] "a" "b"
#>  $ num  : int [1:3] 1 2 3
#>  $ mat  : int [1:10, 1] 1 2 3 4 5 6 7 8 9 10
#>  $ list1:List of 2
#>   ..$ c: chr "c"
#>   ..$ d: chr "d"
#>  $ 1    : num 1
#>  $ 2    : num 2

说明

  • 使用 how = "flatten" 将结果 return 作为扁平化列表
  • 我们设置 classes = c("list", "ANY") 来评估(中间)list 元素,这使我们能够避免扁平化 list1 元素。
  • condition 函数表示应该评估哪些元素,并且由于未指定 f,因此评估的元素只是按原样 returned。特别是,我们检查一个元素是否命名为 "list1" 或者是 data.frame、字符或数字对象,在这种情况下它是 returned 的。否则,rrapply() 将递归到元素的更深处(例如 list2list3)。

数据

## switch names list1 and list2
example_list <- list(
  list2 = list(data = mtcars, char = c("a","b")),
  num = c(1:3),
  mat = matrix(1:10),
  list1 = list(c = "c", d = "d"),
  list3 = list(1, 2)
)