Søren Højsgaard
2005-Jul-04 23:51 UTC
[R] Problems with eval() in connection with match.call()
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 foundMy 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()?? Thanks in advance, S??ren
Douglas Bates
2005-Jul-05 00:33 UTC
[R] Problems with eval() in connection with match.call()
On 7/4/05, S??ren H??jsgaard <Soren.Hojsgaard at agrsci.dk> 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.Welcome to the world of lazy evaluation. Arguments are evaluated only when needed (i.e. when first referenced) not at the time of building the function call. That's why the default value of an argument can depend on previously calculated results within the function.> Should I do something explicitely in foo() to 'evaluate' xx or need I do something special in bar()??Change the eval(cl$x) to eval(cl$x, parent.frame())> barfunction(...){ cl <- match.call(expand.dots=TRUE) print(cl) x <- eval(cl$x, parent.frame()) print(x) }> foo()bar(x = xx) [1] 111222> Thanks in advance, S??ren > > ______________________________________________ > R-help at 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 >
Duncan Murdoch
2005-Jul-05 00:37 UTC
[R] Problems with eval() in connection with match.call()
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
Apparently Analagous Threads
- Understanding eval
- "eval" inside a function call in connection with updating the data slot in the call of lmer
- Calling update on an lm-object inside a function
- Error in load(zfile, envir = envir) : input has been corrupted, with LF replaced by CR
- Seeing the definition of a function