使用purrr和map循环遍历列表的深层元素?

3

我想知道如何从嵌套列表的第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')
    )
  )
)

1
你是否在这种情况下寻找类似于 map_depth(testlist2, 3, "veggie") %>% unlist() 的东西? - undefined
1
或者testlist2 %>% map(map_chr, map_chr, "veggie") - undefined
2个回答

2
正如@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)

1
如何取消数据的列表,并选择所需名称的元素?
temp <- unlist(testlist2)
unname(temp[names(temp) == "veggie"])
#[1] "apple"    "banana"   "tomato"   "pickle"   "chestnut" "seaweed" 

这将在数据多层深度时也能正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接