[英]Use match.call to pass all arguments to other function
From ?match.call
:从
?match.call
:
match.call
is most commonly used in two circumstances: […] To pass most of the call to another function […]match.call
最常用于两种情况: […] 将大部分调用传递给另一个函数 […]
After reading that, I expected I could use match.call
when I want to pass all arguments of one function to another function without listing these arguments one by one.读完之后,我希望当我想将一个函数的所有参数传递给另一个函数而不一一列出这些参数时,我可以使用
match.call
。
Example: outer1
passes arguments one by one, outer2
uses match.call
.示例:
outer1
一个接一个地传递参数, outer2
使用match.call
。
outer1 <- function(a, b, c) {
inner1(a, b, c)
}
inner1 <- function(a, b, c) {
return(a + b + c$first + c$second)
}
outer2 <- function(a, b, c) {
mycall <- match.call()
inner2(mycall)
}
inner2 <- function(call) {
return(call$a + call$b + call$c$first + call$c$second)
}
outer1(1, 2, list(first = 3, second = 4)) # OK: 10
outer2(1, 2, list(first = 3, second = 4)) # OK: 10
The first problem arises, when -1
instead of 1
is passed to outer2
:第一个问题出现了,当
-1
而不是1
传递给outer2
:
outer2(-1, 2, list(first = 3, second = 4)) # Error in call$a + call$b : non-numeric argument to binary operator
Question 1 : What is the technical difference between passing -1
instead of 1
?问题 1 :传递
-1
而不是1
之间的技术区别是什么? I know that我知道
typeof(quote(1)) # double
typeof(quote(-1)) # language
but I suppose that the fact that I passed a language
object in the second case is not the (only) relevant difference because passing something of type language to argument c
works ( typeof(quote(list(first = 3, second = 4))) # language
).但我想我在第二种情况下传递
language
对象的事实并不是(唯一的)相关差异,因为将类型语言的某些内容传递给参数c
有效的( typeof(quote(list(first = 3, second = 4))) # language
)。
In order to overcome the problem above, I try to eval
all arguments that are of type language
:为了克服上述问题,我尝试
eval
所有类型为language
参数:
outer3 <- function(a, b, c) {
parsedCall <- lapply(match.call()[-1L], FUN=function(argument) {
if(is.language(argument)) {
return(eval(argument))
} else {
return(argument)
}
})
inner3(parsedCall)
}
inner3 <- function(parsedCall) {
return(parsedCall$a + parsedCall$b + parsedCall$c$first + parsedCall$c$second)
}
outer3(-1, 2, list(first = 3, second = 4)) # OK: 8
Question 2: The approach in outer3
seems to "work" but are there further pitfalls I need to take into account?问题 2:
outer3
的方法似乎“有效”,但我还需要考虑其他陷阱吗? (I know that in some cases it might be disadvantageous to evaluate the arguments but for my case this should not be an issue.) (我知道在某些情况下评估论点可能是不利的,但就我而言,这应该不是问题。)
Question 3: I suppose that the desire to pass all arguments to another function is not very uncommon.问题 3:我想将所有参数传递给另一个函数的愿望并不少见。 Is there a better/standard approach than what I did?
有没有比我做的更好/标准的方法?
Question 4: Is it advantageous to pass the raw call
to the inner function an do the eval
stuff there?问题 4:将原始
call
传递给内部函数并在那里执行eval
内容是否有利? Would this be helpful if I would like to have the arguments as local variables in the inner
functions (instead of elements of the parsedCall
list)?如果我想将参数作为
inner
函数中的局部变量(而不是parsedCall
列表的元素),这会有所帮助吗? Then, the body of inner3
could be identical to the body of inner1
(while with the current solution, I have to replace a+b
with parsedCall$a + parsedCall$b
).然后,身体
inner3
可以是相同的主体inner1
(而与当前的解决方案,我必须更换a+b
与parsedCall$a + parsedCall$b
)。
Regarding your question:关于你的问题:
I suppose that the desire to pass all arguments to another function is not very uncommon.
我想将所有参数传递给另一个函数的愿望并不少见。 Is there a better/standard approach than what I did?
有没有比我做的更好/标准的方法?
Then I would say this is a more common way to pass the arguments on:然后我会说这是一种更常见的传递参数的方式:
inner1 <- function(a, b, c) {
return(a + b + c$first + c$second)
}
outer3 <- function(a, b, c) {
mycall <- match.call()
mycall[[1]] <- as.symbol("inner1") # use inner 1
eval(mycall)
}
outer4 <- function(a, b, c) {
.args <- as.list(match.call()[-1])
do.call(inner1, .args)
}
outer3(-1, 2, list(first = 3, second = 4))
#R> [1] 8
outer4(-1, 2, list(first = 3, second = 4))
#R> [1] 8
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.