首页 > 解决方案 > 使用 purrr 和 map 遍历列表的更深层?

问题描述

我正在尝试查看如何从嵌套列表的第 n 级中提取值。例如......如果这些都在第二层,我可以map()像这样使用:

> testlist1 <- 
+   list(
+     list('veggie' = 'apple', 'food' = 'bacon'),
+     list('veggie' = 'banana', 'food' = 'burger'),
+     list('veggie' = 'tomato', 'food' = 'sausage'),
+     list('veggie' = 'pickle', 'food' = 'chicken'),
+     list('veggie' = 'chestnut', 'food' = 'salmon'),
+     list('veggie' = 'seaweed', 'food' = 'tuna')
+   )
> 
> testlist1 %>% map('veggie')
[[1]]
[1] "apple"

[[2]]
[1] "banana"

[[3]]
[1] "tomato"

[[4]]
[1] "pickle"

[[5]]
[1] "chestnut"

[[6]]
[1] "seaweed"

但是当它们更深时,我想一定有某种map()方法可以循环到这些层?例子:

testlist2 <- list(
  list(
    list(
      list('veggie' = 'apple', 'food' = 'bacon')
    ), 
    list(
      list('veggie' = 'banana', 'food' = 'burger')
    )
  ),
  list(
    list(
      list('veggie' = 'tomato', 'food' = 'sausage')
    ), 
    list(
      list('veggie' = 'pickle', 'food' = 'chicken')
    )
  ),
  list(
    list(
      list('veggie' = 'chestnut', 'food' = 'salmon')
    ), 
    list(
      list('veggie' = 'seaweed', 'food' = 'tuna')
    )
  )
)

标签: rpurrr

解决方案


正如@MrFlick 建议的那样,map_depth可以在这里提供帮助

library(tidyverse)

testlist2 <- list(
  list(
    list(
      list('veggie' = 'apple', 'food' = 'bacon')
    ), 
    list(
      list('veggie' = 'banana', 'food' = 'burger')
    )
  ),
  list(
    list(
      list('veggie' = 'tomato', 'food' = 'sausage')
    ), 
    list(
      list('veggie' = 'pickle', 'food' = 'chicken')
    )
  ),
  list(
    list(
      list('veggie' = 'chestnut', 'food' = 'salmon')
    ), 
    list(
      list('veggie' = 'seaweed', 'food' = 'tuna')
    )
  )
)

使用第一个参数设置所需的列表深度

testlist2 %>% map_depth(3, 'veggie')
#> [[1]]
#> [[1]][[1]]
#> [[1]][[1]][[1]]
#> [1] "apple"
#> 
#> 
#> [[1]][[2]]
#> [[1]][[2]][[1]]
#> [1] "banana"
#> 
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#> [[2]][[1]][[1]]
#> [1] "tomato"
#> 
#> 
#> [[2]][[2]]
#> [[2]][[2]][[1]]
#> [1] "pickle"
#> 
#> 
#> 
#> [[3]]
#> [[3]][[1]]
#> [[3]][[1]][[1]]
#> [1] "chestnut"
#> 
#> 
#> [[3]][[2]]
#> [[3]][[2]][[1]]
#> [1] "seaweed"

或者用负数从最低层往上数

testlist2 %>% map_depth(-2, 'veggie')
#> [[1]]
#> [[1]][[1]]
#> [[1]][[1]][[1]]
#> [1] "apple"
#> 
#> 
#> [[1]][[2]]
#> [[1]][[2]][[1]]
#> [1] "banana"
#> 
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#> [[2]][[1]][[1]]
#> [1] "tomato"
#> 
#> 
#> [[2]][[2]]
#> [[2]][[2]][[1]]
#> [1] "pickle"
#> 
#> 
#> 
#> [[3]]
#> [[3]][[1]]
#> [[3]][[1]][[1]]
#> [1] "chestnut"
#> 
#> 
#> [[3]][[2]]
#> [[3]][[2]][[1]]
#> [1] "seaweed"

Created on 2019-11-18 by the reprex package (v0.3.0)

推荐阅读