Try this for timesDefineInside:

timesDefineInside <- function(foo, ...) {
    extra.args <-   list(...)
    bar <- extra.args$bar
    foo * bar
}

-Kaom

On Oct 19, 2008, at 6:34 PM, Sietse Brouwer wrote:

> Dear R-helpers,
>
> I've got two functions; callTimes() calls times(), passing it an
> optional argument (bar) by name (bar=harry). times() then believes it
> has been passed a name, rather than a value — but I want the value,
> not the name.
> Worse, if I evaluate the name, it is evaluated in the environment
> times() was defined, not where it is called.
> How can I call times(), defining its optional argument as a variable,
> and have times() know the variable's value (at the moment of calling)?
>
> Below some code:
> (1) The basic case
> (2) A working kludge-around (but I'm still looking for the Right Way.)
> (3) A bunch of variants, so that you may get an idea of the  
> behaviour involved.
>
> (3 starts from the simplest case and builds up from there. Think of it
> as background reading.)
>
> Actually, I'll put (1) up here:
>
> ########################
> ## (1) The basic case ##
>
> ## The calling function
> ## passes an optional argument (bar), as a variable (bar=harry).
> callTimes <- function(tom, harry) {
>    print(match.call(expand.dots=TRUE)) # callTimes(tom = 2, harry = 7)
>    timesDefineInside(foo=tom, bar=harry)
> }
>
> ## The called function
> ## does not explicitly ask for bar.
> timesDefineInside <- function(foo, ...) {
>    # Checks to ensure this code is only executed if bar is given.
>    print(match.call(expand.dots=TRUE))    # times(foo = tom, bar =  
> harry)
>    bar <- match.call(expand.dots=TRUE)$bar
>    print(foo)                             # [1] 2
>    print(bar)                             # harry
>    print(mode(bar))                       # "name"
>    print(eval(bar))                       # [1] 13
>    foo*bar    # Error in foo * bar : non-numeric argument to binary  
> operator
> }
>
> harry <- 13  # Now, let's see whether it thinks harry==13, or harry==7
> callTimes(2, 7)
> ## For the output, see the above inline comments.
>
> ## And THERE we have my problem. I have yet to find a way to call a  
> function,
> ## give one of the optional arguments as argument=variable, and have  
> it pick up
> ## on that variable's *value*, rather than its name. (It's not even  
> the
> ## reference it picks up on: as you can see, if I evaluate the name,  
> it uses
> ## the definition environment, rather than the calling environment.
>
> (For the work-around, scroll down.)
>
> A second question, not essential: I spent a while searching on this
> topic, and found myself unsure of the terminology. Tried a number of
> things, found nothing, now I'm not sure whether that's because I
> didn't know the right words. How would you phrase/define this problem?
>
> Kind regards, and thanks in advance,
>
> Sietse
> Sietse Brouwer
>
> #################
> ## Code below. ##
> ## Two comment-signs for comments, one for output, none for input.
>
> ##########################
> ## (2) A working kludge ##
>
> ## I can kludge around it by using
> callTimes <- function(tom, harry) {
>    timesArgs <- list(foo = tom, bar = harry)
>    do.call(times, timesArgs)
> }
> ## ; but is there a Right Way, too?
>
>
> ############################################################
> ## (3) Some variants, starting from the simplest case... ##
> ## ...and increasing in complexity.
>
>
> ## (3.1) This is the function I have trouble with: I can't get it to  
> get bar
> ## from the arguments.
> times <- function(foo, ...) {
>    print(match.call(expand.dots=TRUE))
>    # Some checks and a guard statement.  You can safely assume that  
> if there
>    # ain't no bar argument (bar fight?), this part will not be  
> reached.
>    foo*bar
> }
>
> ## here we run it, and see that it gets bar not from
> ## the argument list, but from the defining environment.
> ls(bar)
> # Error in as.environment(pos) : no item called "bar" on the search  
> list
> times(foo=2, bar=3)
> # times(foo = 2, bar = 3)
> # [1] Error in times(foo = 2, bar = 3): object "bar" not found
> ## Somehow, it doesn't cotton on to the fact that there's a bar
> ## in the argument list.
> bar <- 5
> times(foo=2, bar=3)
> # [1] 10
> ## Ah. it looks for bar in the environment where the function was  
> defined, not
> ## in the one where it is evaluated. Lexical scoping, plus a rule of
> ## inheritance/who's-your-parent-now that I don't quite understand.
>
> ## (3.2) Now we try explicitly getting it from the argument list.
> rm(bar)
> timesDefineInside <- function(foo, ...) {
>    print(match.call(expand.dots=TRUE))
>    # again, imagine checks here.
>    bar <- match.call(expand.dots=TRUE)$bar
>    foo*bar
> }
> timesDefineInside(foo=7, bar=11)
> # [1] 77
>
> ## So this works, and all is well, nay? Nay. Turn thou to (1) to see  
> what
> ## doth happen when we call timesDefineInside from inside another  
> function.
>
> -- 
> Sietse Brouwer -- sbbrouwer@gmail.com -- +31 6 13456848
> Wildekamp 32 -- 6721 JD Bennekom -- the Netherlands
> MSN: sietse@gawab.com -- ICQ: 341232104
>
> ______________________________________________
> R-help@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.


	[[alternative HTML version deleted]]

