为什么purrr::map不支持引号插值?

4

我很好奇为什么purrr::map_*函数族尽管是tidyverse的一部分,但在评估映射函数之前不支持通过展开引用其dots来进行准引用?

library(tidyverse)
library(rlang)

set.seed(1)
dots <- quos(digits = 2L)

# this obviously won't work
purrr::map_chr(rnorm(5L), 
               ~ format(.x, !!!dots))
#> Error in !dots: invalid argument type

# I'm confused why this does not work
purrr::map_chr(rnorm(5L), 
               ~ format(.x, ...), 
               !!!dots)
#> Error in !dots: invalid argument type

# Finally, this works
eval_tidy(expr(
  purrr::map_chr(rnorm(5L), 
                 ~ format(.x, ...), 
                 !!!dots)
))
#> [1] "1.5"   "0.39"  "-0.62" "-2.2"  "1.1"

这段代码是使用 reprex包 (v0.2.0) 于2019-01-31创建的。

1个回答

3

我认为问题在于format不支持简洁的点符号 -- 你可以使用exec来强制函数能够使用它们:

library(tidyverse)
library(rlang)

set.seed(1)

nums <- rnorm(5L) #for some reason couldn't replicate your numbers
nums
#[1] -0.6264538  0.1836433 -0.8356286  1.5952808  0.3295078

dots <- exprs(digits = 2L)

map_chr(nums, ~exec(format, .x, !!!dots))
#[1] "-0.63" "0.18"  "-0.84" "1.6"   "0.33"

您还需要使用exprs而不是quos来捕获附加的函数参数,以使其正常工作(说实话,我不太确定为什么quos在这里无法工作)。


没错,这就是为什么会返回错误。然而我的担忧在于为什么在调用函数之前没有将参数解开(例如像rlang::call2那样)。 - mjktfw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接