r - 路过。. . 使用 tidyeval 到 `map()`
问题描述
我想使用 quosure将点传递...
给我,以便我可以评估提供的论点。map()
直接传递...
有效,但引用...
和拼接 using!!!
会导致错误。
我尝试过使用各种 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()
,它旨在做同样的事情,但使用 tidy 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 来评估点?
解决方案
没有办法做到这一点purrr::map()
。点按原样传递给映射函数,没有任何更改。因此,映射函数的职责是通过...
使用enquos()
or捕获来实现整齐的点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
推荐阅读
- python - QGroupBox 中的 QButton 布局,用于在 PyQt5 中制作 UI
- isabelle - 如何使用 get 使前向消除证明更易于阅读?
- laravel - 验证永远不起作用
- nginx - osrm 无效的网址
- javascript - 记录邮递员运行数据(cvs)参数
- python-3.6 - 在 Ubuntu 18.04 上导入时出现问题
- javascript - React 的差异算法如何处理元素列表?
- javascript - RecordRTC 错误:MediaRecorder API 似乎无法录制 mimeType:audio/wav
- c# - jquery ajax 发布数据在控制器处始终为 Null
- android - 用于延迟加载 RecyclerView 的 ScrollToPosition