如何用tidyverse在同一管道中处理列表不同层级的array转data.frame需求
解决方案
library(tidyverse) # 原始列表 a <- list("aa" = array(c(c(1, 2, 3), c(3, 2, 1)), dim = c(3, 4)), "bb" = array(c(c(7, 8, 9), c(10, 11, 12)), dim = c(3, 4, 2))) # 单管道处理代码 res <- a %>% map_if( # 判断是否为三维数组(对应a[["bb"]]类元素) .p = ~ length(dim(.x)) == 3, # 三维数组按第三维拆分后逐个转data.frame .f = ~ array_branch(.x, margin = 3) %>% map(data.frame), # 二维数组直接转data.frame .else = ~ data.frame(.x) )
说明
- 用
purrr::map_if()做条件分支处理,无需中断管道即可对不同结构的列表元素做差异化操作 array_branch()是purrr内置的数组拆分工具,margin = 3指定按第三维拆分,会把三维数组拆成多个二维数组组成的列表,再对每个子元素调用data.frame()就能得到你需要的bb结构- 二维数组
aa直接走.else分支转成data.frame即可
结果验证
调用str(res)可查看输出结构,完全符合需求:
str(res) # List of 2 # $ aa:'data.frame': 3 obs. of 4 variables: # ..$ X1: num [1:3] 1 2 3 # ..$ X2: num [1:3] 3 2 1 # ..$ X3: num [1:3] 1 2 3 # ..$ X4: num [1:3] 3 2 1 # $ bb:List of 2 # ..$ :'data.frame': 3 obs. of 4 variables: # .. ..$ X1: num [1:3] 7 8 9 # .. ..$ X2: num [1:3] 10 11 12 # .. ..$ X3: num [1:3] 7 8 9 # .. ..$ X4: num [1:3] 10 11 12 # ..$ :'data.frame': 3 obs. of 4 variables: # .. ..$ X1: num [1:3] 7 8 9 # .. ..$ X2: num [1:3] 10 11 12 # .. ..$ X3: num [1:3] 7 8 9 # .. ..$ X4: num [1:3] 10 11 12
内容的提问来源于stack exchange,提问作者J. Doe
相关产品推荐
相关产品推荐

