假设我在 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
将是 b
和 d
的函数,并返回 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
返回一个存储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
但是对于后者,您必须在
b
中命名d
和f()
参数,以避免在您想将a
和c
保留为默认值时出现错误。
你也有
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
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