Re: [R] Problems with eval() in connection with match.call()

From: Duncan Murdoch <murdoch_at_stats.uwo.ca>
Date: Tue 05 Jul 2005 - 10:37:41 EST

Søren Højsgaard wrote:
> Dear all, I have a problem when passing parms from one function to another when the argument list is just '...'. Consider this example:
>
> foo<-function(){
> xx <- 111222
> bar(x=xx)
> }
> bar <- function(...){
> cl <- match.call(expand.dots=TRUE)
> print(cl)
> x <- eval(cl$x)
> print(x)
> }
> foo()
>
>

>>bar(x = xx)
>>Error in eval(expr, envir, enclos) : Object "xx" not found

>
>
> My expectation was, that xx would be evaluated to 111222 in foo before being passed on to bar, but obviously it is not so. Should I do something explicitely in foo() to 'evaluate' xx or need I do something special in bar()??

Hi Søren.

You need to use eval.parent(cl$x) (which is the same as eval(cl$x, envir=parent.frame())) to get what you want. You want the evaluation to happen in the caller's frame of reference, not in bar's frame.

Generally when you eval() an expression, evaluation takes place in the current frame: the function's local frame when it's in a function, the global frame when you do it at a command line. You can use the envir= argument to change where it takes place.

Things look different when you have named parameters, e.g.

bar <- function(x) {
print(x)
}

because in this case, the argument gets turned into a "promise" at the time of the call, and a promise knows its own evaluation frame. There's nothing really special about named parameters though, e.g.

 > bar <- function(...) {

+  cl <- list(...)
+  print(cl$x)
+ }

 > foo()
[1] 111222

By using match.call, you ignore the environment, and only see the expression.

I imagine you could put together an example where eval.parent() gets the evaluation wrong, e.g. because you want to evaluate in the parent's parent. I was a little surprised that it didn't happen here:

 > foo
function(){
  xx <- 111222
  bar2(x=xx)
}
 > bar2
function(...) { bar(...) }
 > bar
function(...){

   cl <- match.call(expand.dots=TRUE)
   print(cl)
   x <- eval.parent(cl$x)
   print(x)
}
 > foo()
bar(x = ..1)
[1] 111222

I guess match.call() works hard to be helpful.

Duncan Murdoch



R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html Received on Tue Jul 05 10:40:19 2005

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:33:12 EST