Carl Carl - 1 month ago 4
R Question

Issue with match.call

I wrote a function that uses

match.call
, and it works when I call the function directly, however, when the function is called within another function it breaks. I believe it has to do with how
match.call
handles environments, but I can't figure it out. Here is a reproducable example:

tester <- function() {

var <- "helloworld"

myFunc(var)

}


myFunc <- function(x) {

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

}

tester() # error

myFunc("helloworld") # works fine


I believe that when
myFunc
is called within
tester
it can't find
var
because it exists in the isolated environment of the
tester
function.

Any ideas on how to get
myFunc
to work inside
tester
would be appreciated. I've tried changing the environment for
eval
and
match.call
, but to no avail.

Answer

Your suspicion is exactly right.

The very simple solution is to evaluate the function in its parent’s context: replace eval with eval.parent.

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

Generally, the function traceback can help tremendously with debugging similar issues:

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

Ok, but which “closure” (= function) are we talking about?

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

The first line has the clue: toupper(x = var). In the context of tester, var refers to the function (closure) stats::var which is found because its package is attached.

Comments