purrr:遍历带有map的命名列表(带有函数工厂)

时间:2018-10-04 18:46:10

标签: r purrr

我想遍历一个命名列表(带有地图),但是某种程度上单个列表的工作原理却无法实现。这里有什么问题,我必须进行什么更改才能使其正常工作?

我怀疑它有某事。与list[1]list[[1]]之间的区别有关,但我不知道它是atm。

library(rlang)
library(tidyverse)

# this works
single_list <- list(one = 1)

create_function <- function(mylist){
  function(){
    x <- names(mylist)
    n <- purrr::flatten_chr(mylist)

    rep(x, n)
  }
}

one <- create_function(single_list)
one()
#> [1] "one"


# this doesn't work
long_list <- list(one = 1,
                  two = 2,
                  three = 3)

fun <- long_list %>% 
  map(create_function)

fun$one()
#> Error: `.x` must be a list (double)

2 个答案:

答案 0 :(得分:1)

map进行迭代时,它会自动子集化为每个元素的内容,因此您在数字矢量上调用flatten_chr,这会引发错误。删除flatten_chr调用实际上不会解决任何问题,因为名称没有通过map传递,因此调用函数时只会得到NULL

一个好的方法是将factory函数更改为采用两个参数,因此您可以遍历内容和名称。 purrr::imap自动执行此迭代,因此您可以编写

library(purrr)

create_function <- function(n, x){
    function(){
        rep(x, n)
    }
}

list(one = 1,two = 2,three = 3) %>% 
    imap(create_function) %>% 
    map(invoke)    # call each function in list
#> $one
#> [1] "one"
#> 
#> $two
#> [1] "two" "two"
#> 
#> $three
#> [1] "three" "three" "three"

答案 1 :(得分:0)

函数创建的方式,需要输入list

map(seq_along(long_list), ~ create_function(long_list[.x])())
#[[1]]
#[1] "one"

#[[2]]
#[1] "two" "two"

#[[3]]
#[1] "three" "three" "three"