如何有效地部分应用 R 中的函数?

How to efficiently partially apply a function in R?

假设我在 R 中有一个接受多个参数的函数,我想通过将一些参数设置为预先指定的值来将它缩减为一个参数较少的函数。我正在尝试找出在 R 中执行此操作的最佳方法。

例如,假设我有一个函数

f <- function(a,b,c,d){a+b+c+d}

我想创建或找到一个可以执行以下操作的函数部分

partial <- function(f, ...){
#fill in code here
}
new_f <- partial(f, a=1, c= 2)

new_f 将是 bd 的函数,并且 return 1+b+2+d

在python我会

from functools import partial

def f(a,b,c,d):
    return a+b+c+d

new_f = partial(f, a=1, c= 2)

我实际上反复这样做,所以我需要尽可能高效。任何人都可以指出我最有效的方法吗?现在我能做的最好的就是

partial <- function(f, ...){
    z <- list(...)
    formals(f) [names(z)] <- z
    f
}

任何人都可以让我知道更快的方法或最好的方法吗?这简直太慢了。

您可以使用 do.call:

无需过多编码就可以推出自己的产品
partial <- function(f, ...) {
  l <- list(...)
  function(...) {
    do.call(f, c(l, list(...)))
  }
}

基本上 partial returns 一个存储 f 以及最初提供的参数(存储在列表 l 中)的函数。调用此函数时,它会传递 l 中的参数和任何其他参数。这是实际操作:

f <- function(a, b, c, d) a+b+c+d
p <- partial(f, a=2, c=3)
p(b=0, d=1)
# [1] 6

pryr 包中有函数可以处理这个问题,即 partial()

f <- function(a, b, c, d) a + b + c + d 
pryr::partial(f, a = 1, c = 2)
# function (...) 
# f(a = 1, c = 2, ...)

所以你可以这样使用它 -

new_fun <- pryr::partial(f, a = 1, c = 2)
new_fun(b = 2, d = 5)
# [1] 10
## or if you are daring ...
new_fun(2, 5)
# [1] 10

您也可以简单地将 f() 的形式参数更改为

f <- function(a, b, c, d) a + b + c + d 
formals(f)[c("a", "c")] <- list(1, 2)
f
# function (a = 1, b, c = 2, d) 
# a + b + c + d
f(b = 2, d = 5)
# [1] 10

但是对于后者,您必须f()中命名bd参数以避免在您想要将 ac 保留为默认值。

您还 Curry 来自包 functional:

library(functional)

f <- function(a, b, c, d) a+b+c+d
ff = Curry(f, a=2, c=10)

ff(1,5)
#[1] 18

ff(b=1,d=5)
#[1] 18