【问题标题】:purrr::possibly function possibly not working with map2_chr functionpurrr::possibly function 可能不适用于 map2_chr 函数
【发布时间】:2019-01-14 03:12:41
【问题描述】:

我怀疑这是 purrr 包中的错误,但请先检查我在 StackOverflow 中的逻辑。

在我看来 possibly 函数在 map2_chr 函数中不起作用。我正在使用 purrr 版本 0.2.5

考虑这个例子:

library(dplyr)
library(purrr)

lets <- tibble(posn = 2:0,
               lets_list = list(letters[1:5], letters[1:5], letters[1:5])) %>% 
  glimpse()

返回

Observations: 3
Variables: 2
$ posn      <int> 2, 1, 0
$ lets_list <list> [<"a", "b", "c", "d", "e">, <"a", "b", "c", "d", "e">, <"a", "b", "c", "d", "e">]

在此示例中,我想使用 mutate 创建另一个列,以根据“posn”中的值返回列表“lets_list”中的元素。

lets %>% 
  mutate(lets_sel = map2_chr(lets_list, posn, ~.x[.y]))

由于第三行的 posn = 0 导致此错误消息失败。

> lets %>% 
+   mutate(lets_sel = map2_chr(lets_list, posn, ~.x[.y]))
#    Error in mutate_impl(.data, dots) : 
#      Evaluation error: Result 3 is not a length 1 atomic vector.

possibly 函数与map2_chr 一起使用也会返回错误。

lets %>% 
  mutate(lets_sel = map2_chr(lets_list, posn, possibly(~.x[.y], NA_character_)))
# Error in mutate_impl(.data, dots) : 
#  Evaluation error: Result 3 is not a length 1 atomic vector.

但是,map2 函数可以正常工作:

> lets %>% 
+   mutate(lets_sel = map2(lets_list, posn, possibly(~.x[.y], NA_character_)))
# A tibble: 3 x 3
   posn lets_list lets_sel 
  <int> <list>    <list>   
1     2 <chr [5]> <chr [1]>
2     1 <chr [5]> <chr [1]>
3     0 <chr [5]> <chr [0]>

解决方法是先使用 map2,然后使用 map_chr,但我怀疑这是一个错误。

> lets %>% 
+   mutate(lets_sel = map2(lets_list, posn, ~.x[.y]),
+          lets_sel = map_chr(lets_sel, possibly(~.x[1], NA_character_)))
    # A tibble: 3 x 3
       posn lets_list lets_sel
      <int> <list>    <chr>   
    1     2 <chr [5]> b       
    2     1 <chr [5]> a       
    3     0 <chr [5]> NA      

我在这里遗漏了什么吗? 谢谢。

【问题讨论】:

  • 刚刚意识到在我的解决方案中,map2 函数中可能不需要,所以我更改了可重现的示例。我的问题仍然成立。谢谢。

标签: r purrr


【解决方案1】:

好的,现在我认为这只是一个“功能”。最优雅的解决方案/解决方法就是:

lets %>% 
  mutate(lets_sel = map2(lets_list, posn, ~.x[.y]) %>% 
           map_chr(., possibly(~.x[1], NA_character_)))

帮助屏幕中没有任何地方建议安全且可能可以与map2 系列函数一起使用。因此,我得出结论,这是一个“功能”而不是“错误”。
谢谢。

【讨论】:

    【解决方案2】:

    possibly() 不起作用,因为使用0 进行索引不会引发错误; 它只返回一个长度为 0 的向量:

    nth_letter <- function(n) letters[n]
    
    possibly(nth_letter, "not returned")(0)
    #> character(0)
    
    nth_letter(0)
    #> character(0)
    

    在这种情况下,用NA 替换无效索引可能会更容易 (使用例如dplyr::na_if(),或者如果真正的问题更复杂,则使用普通的旧ifelse)来获得你想要的:

    lets %>% 
      mutate(lets_sel = map2_chr(lets_list, na_if(posn, 0), ~ .x[.y]))
    #> # A tibble: 3 x 3
    #>    posn lets_list lets_sel
    #>   <int> <list>    <chr>   
    #> 1     2 <chr [5]> b       
    #> 2     1 <chr [5]> a       
    #> 3     0 <chr [5]> <NA>
    

    reprex package (v0.2.0.9000) 于 2018 年 8 月 7 日创建。

    【讨论】:

      猜你喜欢
      • 2020-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多