【发布时间】:2020-06-25 23:01:44
【问题描述】:
rlang::invoke() 现在已软弃用,purrr::invoke() 已停用。如今,以编程方式调用带有参数列表的函数的整洁方法是什么?
【问题讨论】:
-
你能举一个具体的例子来说明你正在尝试做什么吗?可能没有完全替代品,但可能有替代品来做某件事。
标签: r functional-programming tidyverse
rlang::invoke() 现在已软弃用,purrr::invoke() 已停用。如今,以编程方式调用带有参数列表的函数的整洁方法是什么?
【问题讨论】:
标签: r functional-programming tidyverse
tldr; 使用exec 而不是invoke;使用map2 加上exec 而不是invoke_map。
invoke 的示例
退休invoke
set.seed(2020)
invoke(rnorm, list(mean = 1, sd = 2), n = 10)
#[1] 1.7539442 1.6030967 -1.1960463 -1.2608118 -4.5930686 2.4411470
#[7] 2.8782420 0.5412445 4.5182627 1.2347336
与exec
set.seed(2020)
exec(rnorm, n = 10, !!!list(mean = 1, sd = 2))
#[1] 1.7539442 1.6030967 -1.1960463 -1.2608118 -4.5930686 2.4411470
#[7] 2.8782420 0.5412445 4.5182627 1.2347336
invoke_map 的示例
同样,您可以将map2 与exec 一起使用,而不是invoke_map。以前,您可以使用 invoke_map 来使用具有不同参数集的函数
set.seed(2020)
invoke_map(rnorm, list(list(mean = 0, sd = 1), list(mean = 1, sd = 1)), n = 10)
# [[1]]
# [1] 0.3769721 0.3015484 -1.0980232 -1.1304059 -2.7965343 0.7205735
# [7] 0.9391210 -0.2293777 1.7591313 0.1173668
#
# [[2]]
# [1] 0.1468772 1.9092592 2.1963730 0.6284161 0.8767398 2.8000431
# [7] 2.7039959 -2.0387646 -1.2889749 1.0583035
现在,将map2 与exec 一起使用
set.seed(2020)
map2(
list(rnorm),
list(list(mean = 0, sd = 1), list(mean = 1, sd = 1)),
function(fn, args) exec(fn, n = 10, !!!args))
# [[1]]
# [1] 0.3769721 0.3015484 -1.0980232 -1.1304059 -2.7965343 0.7205735
# [7] 0.9391210 -0.2293777 1.7591313 0.1173668
#
# [[2]]
# [1] 0.1468772 1.9092592 2.1963730 0.6284161 0.8767398 2.8000431
# [7] 2.7039959 -2.0387646 -1.2889749 1.0583035
遗憾的是,map2 加上exec 语法不如invoke_map 简洁,但它可能更规范。
在使用map2 和exec 时可能有助于避免问题的一些cmets:
map2 的第一个参数必须是 list。所以map2(list(rnorm), ...) 会起作用。仅提供map2(rnorm, ...) 的功能不会。这与invoke_map 不同,后者接受list 的函数和函数本身。lists 的list。 map2 将遍历顶层list,然后使用exec 内部的大爆炸运算符!!! 强制拼接函数参数的list。 【讨论】:
已经大约一年了,没有发布明确的替代品。我在这些场景中所做的是创建一个惰性函数调用并对其进行评估。这是一个很好的解耦invoke 或exec 没有,因为调用对象可以传递。
arglist <- list(n = 100, mean = 2, sd = 3)
aFunctionCall <- rlang::call2(rnorm, !!!arglist)
aFunctionCall
rlang::eval_bare(aFunctionCall)
【讨论】: