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

CL.*_*CL. 5 arguments r parameter-passing

来自?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
Run Code Online (Sandbox Code Playgroud)

-1代替1传递给时,出现第一个问题outer2

outer2(-1, 2, list(first = 3, second = 4)) # Error in call$a + call$b : non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)

问题1:传球与传球之间的技术区别-11什么?我知道

typeof(quote(1)) # double
typeof(quote(-1)) # language
Run Code Online (Sandbox Code Playgroud)

但我想我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
Run Code Online (Sandbox Code Playgroud)

问题2:的方法outer3似乎“有效”,但是我还需要考虑其他陷阱吗?(我知道在某些情况下,评估参数可能是不利的,但就我而言,这不应该成为问题。)

问题3:我想将所有参数传递给另一个函数的愿望并不少见。有没有比我做的更好/标准的方法?

问题4:将原始call函数传递给内部函数是否有利eval?那里的东西在那里吗?如果我想将参数作为inner函数中的局部变量(而不是parsedCall列表中的元素),这会有所帮助吗?然后,的主体inner3可能与的主体相同inner1(在当前解决方案中,我必须替换a+bparsedCall$a + parsedCall$b)。

Ben*_*sen 6

关于你的问题:

我想将所有参数传递给另一个函数的愿望并不少见。有没有比我做的更好/标准的方法?

然后我会说这是一种更常见的传递参数的方式:

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
Run Code Online (Sandbox Code Playgroud)