簡體   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