purrr::possibly 函数可能无法与 map2_chr 函数一起使用
purrr::possibly function possibly not working with map2_chr function
我怀疑这是 purrr 包中的错误,但请先在 Whosebug 中检查我的逻辑。
在我看来,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()
returns
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">]
在此示例中,我想根据 "posn".
中的值使用 return 列表 "lets_list" 中的元素变异来创建另一列
lets %>%
mutate(lets_sel = map2_chr(lets_list, posn, ~.x[.y]))
失败并显示此错误消息,因为第三行的位置 = 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
return 一起使用也是一个错误。
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
我是不是漏掉了什么?
谢谢。
好的,现在我认为这只是一个 "feature"。最优雅的解决方案/解决方法是:
lets %>%
mutate(lets_sel = map2(lets_list, posn, ~.x[.y]) %>%
map_chr(., possibly(~.x[1], NA_character_)))
帮助屏幕中没有任何地方建议可以安全且可能地与 map2
系列函数一起使用。因此我得出结论,这是 "feature" 而不是 "bug".
谢谢。
possibly()
不起作用,因为使用 0
进行索引不会引发错误;
它只是 returns 一个长度为 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-08-07。
我怀疑这是 purrr 包中的错误,但请先在 Whosebug 中检查我的逻辑。
在我看来,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()
returns
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">]
在此示例中,我想根据 "posn".
中的值使用 return 列表 "lets_list" 中的元素变异来创建另一列lets %>%
mutate(lets_sel = map2_chr(lets_list, posn, ~.x[.y]))
失败并显示此错误消息,因为第三行的位置 = 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
return 一起使用也是一个错误。
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
我是不是漏掉了什么? 谢谢。
好的,现在我认为这只是一个 "feature"。最优雅的解决方案/解决方法是:
lets %>%
mutate(lets_sel = map2(lets_list, posn, ~.x[.y]) %>%
map_chr(., possibly(~.x[1], NA_character_)))
帮助屏幕中没有任何地方建议可以安全且可能地与 map2
系列函数一起使用。因此我得出结论,这是 "feature" 而不是 "bug".
谢谢。
possibly()
不起作用,因为使用 0
进行索引不会引发错误;
它只是 returns 一个长度为 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-08-07。