我有以下功能
sjbDo <- function(operation, x, statelist, Spos, isFuture = FALSE) {
# run the operation on x
xvec <- operation(x);
# and so on
}
我可以这样称呼它:
A <- sjbDo( function(x) {x}, statelist$A, statelist, 1)
但是,我想修改sjbDo,以便内联函数可以使用其他参数。类似的东西:
kTheta <- sjbDo( function(x, b) {x^b}, statelist$K, statelist, 1, FALSE, b=theta.k)
我试过
sjbDo <- function(operation, x, statelist, Spos, isFuture = FALSE, ...) {
# run the operation on x
xvec <- operation(x,...);
但这似乎不起作用。我怎样才能让它发挥作用?
答案 0 :(得分:6)
更典型的解决方案如下:
operation <- function(x, ...) {
dots <- list(...)
x^dots[[1]]
}
但是如果你知道你想要的参数是第一个作为...
传递的参数,那么你应该把它作为一个参数。因为你的代码(和我的代码)在这样调用时不起作用,例如:
> operation(1:10, foo = "bar", b = 2)
Error in x^dots[[1]] : non-numeric argument to binary operator
如果您按上述方式抓取...
,那么您可以提取所需的参数:
operation <- function(x, ...) {
dots <- list(...)
want <- which(names(dots) == "b")
stopifnot(length(want) > 0)
b <- dots[[want]]
x^b
}
其中的工作原理如下:
> operation(1:10, foo = "bar", b = 2)
[1] 1 4 9 16 25 36 49 64 81 100
但如果b
不是命名参数,则仍然失败:
> operation(1:10, foo = "bar", 2)
Error: length(want) > 0 is not TRUE
因此,您提出的内容可能适用于您提供的一个用例,但这并不是执行您想要执行的操作的更一般策略。如果没有传递额外的参数,operation
应该做什么?您的代码假定还有其他参数,因此不再是可选的 - 这就是您所指出的。如果b
如果提供了non,则应该使用其他一些默认值,那么整个事情就变得更容易了:
operation <- function(x, b = 1) {
x^b
}
sjbDo <- function(FUN, x, ...) {
## function matching
FUN <- match.fun(FUN)
# run the operation on x
xvec <- FUN(x, ...)
xvec
}
给出了:
> sjbDo(operation, 1:10)
[1] 1 2 3 4 5 6 7 8 9 10
> sjbDo(operation, 1:10, b = 2)
[1] 1 4 9 16 25 36 49 64 81 100
> sjbDo("operation", 1:10, b = 2)
[1] 1 4 9 16 25 36 49 64 81 100
后者的作用是因为使用了match.fun
。
上述观点是我认为你不希望operation()
有一个...
参数,因为我看不出这些代码是如何工作的。我想你想要的是一种编写外部函数调用sjbDo()
以获得一些命名参数并将任何其他参数传递给你要在sjbDo()
中调用的函数的方法,我在这里调用{ {1}}你打电话给FUN
。
换句话说,我认为你想要的是一个包装器(operation
),它可以使用参数sjbDo()
调用给定的函数(作为参数FUN
提供),以及任何其他参数x
要求,而不必考虑FUN
所需的所有可能参数?
答案 1 :(得分:0)
哎呀,我想通了
操作&lt; - function(x,...){x ^ ... [[1]]}
非常感谢。