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