使用purrr::map或lapply指定另一个函数的参数及要传递给该参数的值的函数

3

假设我有一个简单的函数:

my_c <- function(x = 1, y = 2, z = 3) {
  c(x, y, z)
}

现在我想创建另一个函数来封装my_c,并使我能够:
  1. 选择要更改的函数参数
  2. 提供一个值列表给该参数
这个新函数vary_my_c的期望输出:
vary_my_c(vary = "y", values = list(10, 11))
[[1]]
[1] 1  10  3

[[2]]
[1] 1  11  3

我的尝试是去解析一个表达式,但是并不成功:
library(tidyverse)
vary_my_c <- function(vary, values, ...) {
  values %>% map(function(param) {
    my_c(eval(parse(text = str_c(vary, "= param"))))
  })
}
# or equivalently with syntactic sugar:
vary_my_c <- function(vary, values, ...) {
  values %>% map(~ my_c(eval(parse(text = str_c(vary, "= .x")))))
}
# gives:
[[1]]
[1] 10  2  3

[[2]]
[1] 11  2  3

我在想这个解决方案是否涉及到rlang :: enquo()!!,而不是eval(parse(text = text)),但我对准引用不够熟悉,无法弄清楚如何进行测试。

1个回答

2

如果以my_c开头的行被替换为以下内容,则第一次尝试将起作用:

eval(parse(text = sprintf("my_c(%s = %s)", vary, param)))

虽然这种方法可以运行,但我建议使用Mapdo.call。不需要任何包并且不使用eval

(也可以使用purrr mapinvoke代替Mapdo.call,需要适当重新排列参数。不需要准引用。)

vary_my_c <- function(vary, values) {
  Map(function(value) do.call(my_c, setNames(list(value), vary)), values)
}

vary_my_c(vary = "y", values = c(10, 11))

提供:

[[1]]
[1]  1 10  3

[[2]]
[1]  1 11  3

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