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

k13*_*k13 24 r function partial-application

假设我在R中有一个带有多个参数的函数,我想通过将一些参数设置为预先指定的值来将其减少为参数较少的函数.我试图找出最好的方法是在R.

例如,假设我有一个功能

f <- function(a,b,c,d){a+b+c+d}
Run Code Online (Sandbox Code Playgroud)

我想创建或找到一个函数partial,它将执行以下操作

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

new_f将是一个功能bd和将返回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)
Run Code Online (Sandbox Code Playgroud)

我实际上反复这样做,所以我需要尽可能高效.谁能指出我最有效的方法呢?现在我能做的最好的就是

partial <- function(f, ...){
    z <- list(...)
    formals(f) [names(z)] <- z
    f
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以告诉我更快的方式或最好的方法吗?这太慢了.

jos*_*ber 23

您可以使用do.call以下方式自行滚动:

partial <- function(f, ...) {
  l <- list(...)
  function(...) {
    do.call(f, c(l, list(...)))
  }
}
Run Code Online (Sandbox Code Playgroud)

基本上partial返回一个存储函数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
Run Code Online (Sandbox Code Playgroud)


Ric*_*ven 18

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, ...)
Run Code Online (Sandbox Code Playgroud)

所以你可以像这样使用它 -

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
Run Code Online (Sandbox Code Playgroud)

你也可以简单地改变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
Run Code Online (Sandbox Code Playgroud)

但是对于后者,您必须命名bd参数,f()以避免在您想要离开时出现错误a并将c其作为默认值.


Col*_*vel 9

你也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
Run Code Online (Sandbox Code Playgroud)