繁体   English   中英

使用 match.call 将所有参数传递给其他函数

[英]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+bparsedCall$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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM