gpt4 book ai didi

r - 如何以编程方式创建 R 函数?

转载 作者:行者123 更新时间:2023-12-02 04:46:34 24 4
gpt4 key购买 nike

Hadley Wickham最近在 r-devel mailing 上问了一个有趣的问题列表,并且无法在 StackOverflow 上找到关于该主题的现有问题,我认为它可能有用,因为它也存在于此处。

换句话说:

R 函数由三个元素组成:参数列表、主体和环境。我们能否通过这三个元素以编程方式构造一个函数?

(在上面的 r-devel 链接中的线程末尾提供了一个相当全面的答案。我会将此留给其他人自行重新创建各种解决方案的基准测试并将其作为答案提供,但请确保如果你这样做,请引用哈德利。如果几个小时后没有人站出来,我会自己做。)

最佳答案

这是对讨论的扩展 here .

我们的三个部分需要是一个参数列表、一个正文和一个环境。

对于环境,我们将默认使用 env = parent.frame()

我们并不真的想要一个常规的旧参数列表,所以我们使用 alist它有一些不同的行为:

"...values are not evaluated, and tagged arguments with no value are allowed"

args <- alist(a = 1, b = 2)

对于正文,我们引用我们的表达式以获得调用:

body <- quote(a + b)

一个选择是将 args 转换为一个配对列表,然后简单地调用函数 function使用 eval:

make_function1 <- function(args, body, env = parent.frame()) {
args <- as.pairlist(args)
eval(call("function", args, body), env)
}

另一种选择是创建一个空函数,然后用所需的值填充它:

make_function2 <- function(args, body, env = parent.frame()) {
f <- function() {}
formals(f) <- args
body(f) <- body
environment(f) <- env

f
}

第三种选择是简单地使用as.function:

make_function3 <- function(args, body, env = parent.frame()) {
as.function(c(args, body), env)
}

最后,这对我来说似乎与第一种方法非常相似,除了我们正在使用一种稍微不同的习语来创建函数调用,使用替换而不是调用:

make_function4 <- function(args, body, env = parent.frame()) {
subs <- list(args = as.pairlist(args), body = body)
eval(substitute(`function`(args, body), subs), env)
}


library(microbenchmark)
microbenchmark(
make_function1(args, body),
make_function2(args, body),
make_function3(args, body),
make_function4(args, body),
function(a = 1, b = 2) a + b
)

Unit: nanoseconds
expr min lq median uq max
1 function(a = 1, b = 2) a + b 187 273.5 309.0 363.0 673
2 make_function1(args, body) 4123 4729.5 5236.0 5864.0 13449
3 make_function2(args, body) 50695 52296.0 53423.0 54782.5 147062
4 make_function3(args, body) 8427 8992.0 9618.5 9957.0 14857
5 make_function4(args, body) 5339 6089.5 6867.5 7301.5 55137

关于r - 如何以编程方式创建 R 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32449028/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com