[英]Is there a way to make match.call + eval combination work when called from a function?
我使用的是 package,它有 2 個功能,最終如下所示:
pkgFun1 <- function(group) {
call <- match.call()
pkgFun2(call)
}
pkgFun2 <- function(call) {
eval(call$group)
}
如果我只調用pkgFun1(group = 2)
,它工作正常。 但我想從 function 調用它:
myFun <- function(x) {
pkgFun1(group = x)
}
myFun(x = 2)
## Error in eval(call$group) : object 'x' not found
如果我不能修改 package 函數,但只能修改myFun
,有什么辦法可以避免這個錯誤?
有類似的問題,例如Issue with match.call或Non-standard evaluation in a user-defined function with lapply 或 with in R ,但我的特殊問題是我無法修改包含eval
調用的代碼部分。
是 pkgFun2 是錯誤的,所以我認為如果沒有一些奇怪的扭曲,你就不走運了。 它需要將適當的環境傳遞給 eval(); 如果你不能修改它,那么你就無法修復它。
這個 hack 可能看起來有效,但在現實生活中它不會:
pkgFun1 <- function(group) {
call <- match.call()
f <- pkgFun2
environment(f) <- parent.frame()
f(call)
}
有了這個,你調用了pkgFun2
的副本,因此它的環境適合評估調用。 它在測試用例中有效,但將來會給您帶來難以言喻的悲痛,因為pkgFun2
本地的所有內容都將在錯誤的位置進行搜索。 例如,
myFun <- function(x) {
eval <- function(...) print("Gotcha!")
pkgFun1(group = x)
}
myFun(x = 2)
# [1] "Gotcha!"
最好是修復pkgFun2
。 這是一個修復:
pkgFun1 <- function(group) {
call <- match.call()
pkgFun2(call, parent.frame())
}
pkgFun2 <- function(call, envir) {
eval(call$group, envir = envir)
}
編輯添加:實際上,還有另一個不那么奇怪的 hack 應該適用於您原來的pkgFun1
和pkgFun2
。 如果您強制x
的評估發生在myFun
中,以便pkgFun1
永遠不會看到表達式x
,它應該可以工作。 例如,
myFun <- function(x) {
do.call("pkgFun1", list(group = x))
}
如果你這樣做,那么在myFun(2)
之后, pkgFun1
變量call
將是pkgFun1(group = 2)
並且你不會得到關於x
的錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.