【问题标题】:purrr: Iterating over a named list with map (with a function factory)purrr:使用 map 迭代命名列表(使用函数工厂)
【发布时间】:2018-10-05 04:54:14
【问题描述】:

我想迭代一个命名列表(带有地图),但不知何故,单个列表的工作方式无法大规模工作。这里有什么问题,我必须改变什么才能让它工作?

我怀疑它有什么。与 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)

【问题讨论】:

  • 您需要listlists 即map(long_list, ~ create_function(list(.x))() )

标签: r purrr


【解决方案1】:

map 迭代时,它会自动对每个元素的内容进行子集化,因此您在数值向量上调用flatten_chr,这会引发错误。删除flatten_chr 调用实际上不会修复任何问题,因为名称不是由map 传递的,所以当你调用函数时你只会得到NULL

一个好的方法是将工厂函数更改为采用两个参数,这样您就可以遍历内容和名称。 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"

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-20
      • 2021-05-17
      • 1970-01-01
      相关资源
      最近更新 更多