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

29

假设我有一个在R语言中接收多个参数的函数,我想通过设置某些参数为预先指定的值来将其缩减为较少参数的函数。我正在尝试弄清楚在R中最好的方法是什么。

例如,假设我有一个函数:

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

我希望创建或找到一个函数"partial",它能够实现以下功能:

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

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)

实际上我一直在重复这个操作,所以我需要尽可能地提高效率。有没有人可以指导我如何以最有效的方式完成这项任务?目前我所能做的最好的就是:

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

有没有人能告诉我更快或最好的方法来完成这个任务?当前速度太慢了。


2
你可以使用 formals(f)[c("a", "c")] <- list(1, 3) 更改其形式参数,或者使用 pryr::partial(f, a = 1, c = 2) - Rich Scriven
感谢您的翻译。我想要的是pryr的partial。 - k13
4个回答

25

你可以使用do.call轻松编写自己的代码:

partial <- function(f, ...) {
  l <- list(...)
  function(...) {
    do.call(f, c(l, list(...)))
  }
}

基本上,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

对于列表作为简单参数,使用以下代码 partial_list<-function(f, L){ function(...){ do.call(f, c(L, list(...))) } } - JP Zhang

21

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的默认值时发生错误。


1
似乎purrr包中也有一个partial函数;不过我不确定它们之间的区别。不过这个帮助我找到了正确的位置,所以点赞! - dwanderson

10

你还可以从functional包中使用Curry

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

1

purrr 包来自于 tidyverse,提供许多函数式编程工具,其中包括部分函数:

library(purrr)
f <- function(a,b,c,d){a+b+c+d}
new_f <- partial(f, a = 1, c = 2)

new_f(3,5)
#> [1] 11

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