我想使用定点将点...
传递给我的map()
,以便评估所提供的参数。
直接传递...
是有效的,但是引用...
并使用!!!
进行拼接会导致错误。
我尝试使用各种rlang函数,例如syms
,quos
,enquos
等。我已尽力阅读Advanced-R第17-20章。
我创建了一个函数f
,该函数从随机正态分布中提取每个数字,直到n
。我可以使用点将其他参数传递给rnorm()
。效果很好。
library(magrittr)
library(purrr)
f <- function(n, ...) {
1:n %>%
map(rnorm, ...)
}
f(2, mean = 10)
#>
#> [[1]]
#> [1] 10.90561
#>
#> [[2]]
#> [1] 11.19031 12.16856
f(2)
#> [[1]]
#> [1] -1.197873
#>
#> [[2]]
#> [1] 1.023398 -2.023645
我创建了第二个功能g()
,该功能旨在执行相同的操作,但要使用整洁的eval。
g <- function(n, ...) {
1:n %>%
map(rnorm, !!!enquos(...))
}
g(3)
#>
#> [[1]]
#> [1] NA
#>
#> [[2]]
#> [1] NA NA
#>
#> Warning messages:
#> 1: In .f(.x[[i]], ...) : NAs produced
#> 2: In .f(.x[[i]], ...) : NAs produced
此实现产生NA
。
为此,我尝试使用list2()
,但仍然无法对其进行评估。有没有办法在地图调用中使用tidyeval评估点?
答案 0 :(得分:1)
无法使用purrr::map()
执行此操作。点将原样传递到映射函数,而无需进行任何更改。因此,映射函数的职责是通过用...
或enquos()
捕获list2()
来实现整洁的点。
您可以做的是创建自己的映射函数,该函数使用支持!!!
的点,创建带有拼接参数的调用,并在输入上进行映射:
map_splice <- function(.x, .f, ...) {
n <- length(.x)
out <- vector("list", n)
# Capture arguments with `!!!` support
args <- list2(...)
# Create call with arguments spliced in
call <- expr(.f(.x[[i]], !!!args))
for (i in seq_len(n)) {
out[[i]] <- eval(call)
}
out
}
h <- function(n, ...) {
map_splice(seq_len(n), rnorm, ...)
}
h(3)
#> [[1]]
#> [1] 0.198766
#>
#> [[2]]
#> [1] 0.99824414 -0.08231719
#>
#> [[3]]
#> [1] 0.5288825 -0.6098536 0.7858720
args <- list(mean = 50, sd = 3)
h(3, !!!args)
#> [[1]]
#> [1] 49.32423
#>
#> [[2]]
#> [1] 57.51101 46.69594
#>
#> [[3]]
#> [1] 53.80943 50.00880 54.96616