match.call问题

时间:2016-10-21 15:51:41

标签: r

我编写了一个使用match.call的函数,它在我直接调用函数时起作用,但是,当函数在另一个函数中调用时它会中断。我认为它与match.call如何处理环境有关,但我无法弄明白。这是一个可重复的例子:

tester <- function() {

  var <- "helloworld"

  myFunc(var)

}


myFunc <- function(x) {

  tmp <- match.call()
  tmp[[1]] <- quote(toupper)
  eval(tmp)

}

tester() # error

myFunc("helloworld") # works fine

我相信在myFunc内调用tester时,它无法找到var,因为它存在于tester函数的隔离环境中。

有关如何让myFunctester内工作的任何想法都将不胜感激。我尝试更改evalmatch.call的环境,但无济于事。

1 个答案:

答案 0 :(得分:5)

你的怀疑是完全正确的。

非常简单的解决方案是在父项的上下文中评估函数:将eval替换为eval.parent

myFunc <- function(x) {
  tmp <- match.call()
  tmp[[1]] <- quote(toupper)
  eval.parent(tmp)
}

通常,函数traceback可以极大地帮助调试类似的问题:

> tester()
Error in as.character(x) :
  cannot coerce type 'closure' to vector of type 'character'

好的,但是我们在讨论“闭包”(=功能)?

> traceback()
5: toupper(x = var)
4: eval(expr, envir, enclos)
3: eval(tmp) at #5
2: myFunc(var) at #5
1: tester()

第一行有线索:toupper(x = var)。在tester的上下文中,var指的是函数(闭包)stats::var,因为它的包附加了。