根据条件展平 R 中的列表

Posted

技术标签:

【中文标题】根据条件展平 R 中的列表【英文标题】:Flatten a list in R based on conditions 【发布时间】:2021-09-22 02:37:39 【问题描述】:

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

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) 元素的类不是 data.frame/matrix/character/numeric 或 (2) 如果元素的名称不是“list2”,我想展平此列表的元素。因此,展平列表应包含以下元素 - 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 的解决方案来解决这个问题,那就太好了。

谢谢!

【问题讨论】:

我有点不清楚list1这个名字在output中的来历,会不会是list1list2这两个名字混淆了? @JorisC。确实。那是一个错字。我已经编辑了问题。 【参考方案1】:

假设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" 将结果作为扁平列表返回 我们还将classes = c("list", "ANY") 设置为评估(中间)list 元素,这样我们就可以避免扁平化list1 元素。 condition 函数表示应评估哪些元素,并且由于未指定 f,因此评估的元素将按原样返回。特别是,我们检查一个元素是否被命名为"list1" 或者是一个data.frame、字符或数字对象,在这种情况下它按原样返回。否则,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)
)   

【讨论】:

谢谢。我的问题中有一个错字。但这是我一直在寻找的答案。

以上是关于根据条件展平 R 中的列表的主要内容,如果未能解决你的问题,请参考以下文章

展平Scala中的元组列表?

如何使用嵌套字典列表展平熊猫数据框中的列

Pandas Dataframe 根据列值将值展平到单元格

如何展平haskell中的列表列表

逐列匹配展平R数据帧中的行

R(purrr)展平命名列表列表以列出并保留名称