【问题标题】:Counter in purrr's map* function familypurrr 的 map* 函数族中的计数器
【发布时间】:2019-06-08 08:11:15
【问题描述】:

在将循环函数应用于向量/列表时,我经常需要某种计数器/索引值。使用基本循环函数时,可以通过将某个初始值连续加 1 来创建此索引。考虑以下示例:

lets <- letters[1:5]

n = 0
for (le in lets){
  n = n+1
  print(paste(le,"has index",n))
}
#> [1] "a has index 1"
#> [1] "b has index 2"
#> [1] "c has index 3"
#> [1] "d has index 4"
#> [1] "e has index 5"

我能够使用purrr 包中的循环函数访问此类索引值的唯一方法是使用map2。有没有更优雅的方式来做到这一点只使用purrr::map()

library(purrr)


map2(lets,1:length(lets),~paste(.x,"has index",.y))

#> [[1]]
#> [1] "a has index 1"
#> 
#> [[2]]
#> [1] "b has index 2"
#> 
#> [[3]]
#> [1] "c has index 3"
#> 
#> [[4]]
#> [1] "d has index 4"
#> 
#> [[5]]
#> [1] "e has index 5"

【问题讨论】:

    标签: r for-loop purrr


    【解决方案1】:

    试试imap

    lets <- letters[1:5]
    purrr::imap(lets, ~paste(.x,"has index",.y))
    #[[1]]
    #[1] "a has index 1"
    
    #[[2]]
    #[1] "b has index 2"
    
    #[[3]]
    #[1] "c has index 3"
    
    #[[4]]
    #[1] "d has index 4"
    
    #[[5]]
    #[1] "e has index 5"
    

    请注意,imap 将使用 .x 的元素名称作为 .y 参数,如果元素已命名。如果你不想那样使用imap(unname(...), ...) - 感谢@Moody_Mudskipper。


    base R 方法可能是

    sprintf("%s has index %d", lets, seq_along(lets))
    # [1] "a has index 1" "b has index 2" "c has index 3" "d has index 4" "e has index 5"
    

    【讨论】:

    • 请注意,imap 将使用元素的名称作为 .y 如果元素被命名,在这种情况下 unname 首先!
    • 感谢您的回答! @一种。 Stam 同时发布了the same answer。我已经接受了他的回答,因为它包含了来自文档的令人讨厌的摘录(并且他的代表较少)。
    【解决方案2】:

    您正在寻找的最接近的近似值是purrr::imap,文档中将其描述为

    如果x 有名称,则为map2(x, names(x), ...) 的简写,如果没有,则为map2(x, seq_along(x), ...)

    以下代码有效:

    lets <- letters[1:5]
    
    purrr::imap(lets, ~print(paste(.x, "has index", .y)))
    

    我假设您实际上是在尝试创建一个新对象并将其存储在一个新变量中。如果您希望显示输出(如本例中,控制台的结果是print),您应该使用等效的函数iwalk,它以不可见的方式返回其输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2019-12-20
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多