[英]Use match.call to pass all arguments to other function
从?match.call
:
match.call
最常用于两种情况: […] 将大部分调用传递给另一个函数 […]
读完之后,我希望当我想将一个函数的所有参数传递给另一个函数而不一一列出这些参数时,我可以使用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
第一个问题出现了,当-1
而不是1
传递给outer2
:
outer2(-1, 2, list(first = 3, second = 4)) # Error in call$a + call$b : non-numeric argument to binary operator
问题 1 :传递-1
而不是1
之间的技术区别是什么? 我知道
typeof(quote(1)) # double
typeof(quote(-1)) # language
但我想我在第二种情况下传递language
对象的事实并不是(唯一的)相关差异,因为将类型语言的某些内容传递给参数c
有效的( typeof(quote(list(first = 3, second = 4))) # 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
问题 2: outer3
的方法似乎“有效”,但我还需要考虑其他陷阱吗? (我知道在某些情况下评估论点可能是不利的,但就我而言,这应该不是问题。)
问题 3:我想将所有参数传递给另一个函数的愿望并不少见。 有没有比我做的更好/标准的方法?
问题 4:将原始call
传递给内部函数并在那里执行eval
内容是否有利? 如果我想将参数作为inner
函数中的局部变量(而不是parsedCall
列表的元素),这会有所帮助吗? 然后,身体inner3
可以是相同的主体inner1
(而与当前的解决方案,我必须更换a+b
与parsedCall$a + parsedCall$b
)。
关于你的问题:
我想将所有参数传递给另一个函数的愿望并不少见。 有没有比我做的更好/标准的方法?
然后我会说这是一种更常见的传递参数的方式:
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.