簡體   English   中英

從 function 調用時,有沒有辦法讓 match.call + eval 組合工作?

[英]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.callNon-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 應該適用於您原來的pkgFun1pkgFun2 如果您強制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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM