[R] evaluating expressions with sub expressions

William Dunlap wdunlap at tibco.com
Fri Jan 29 23:04:07 CET 2010


You asked
   And is there a yet simpler and more
   straightforward way to do the 
   above than what I proposed?

You could use S+, whose substitute() function
   (a) descends into expressions and functions
   (b) has an argument (evaluate=TRUE) so you
       don't need to use do.call when the first
       argument is not a literal
E.g.,
   > e <- expression(a*b, function(x)x+b, log(b))
   > substitute(e, list(b=Quote(exp(1))), evaluate=TRUE)
   expression(a * exp(1), function(x)
   x + exp(1), log(exp(1)))

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com  

> -----Original Message-----
> From: r-help-bounces at r-project.org 
> [mailto:r-help-bounces at r-project.org] On Behalf Of Bert Gunter
> Sent: Friday, January 29, 2010 1:38 PM
> To: 'Gabor Grothendieck'; 'Jennifer Young'
> Cc: r-help at r-project.org
> Subject: Re: [R] evaluating expressions with sub expressions
> 
> Folks:
> 
> Stripped to its essentials, Jennifer's request seemed simple: 
> substitute a
> subexpression as a named variable for a variable name in an 
> expression, also
> expressed as a named variable. A simple example is:
> 
> > e <- expression(0,a*b)
> > z1 <- quote(1/t) ## explained below
> 
> The task is to "substitute" the expression in z1, "1/t", for "b" in e,
> yielding the substituted expression as the result.
> 
> Gabor provided a solution, but it seemed to me like trying to 
> swat a fly
> with a baseball bat -- a lot of machinery for what should be a more
> straightforward task. Of course, just because I think it **should be**
> straightforward does not mean it actually is. But I fooled 
> around a bit
> (guided by Gabor's approach and an old Programmer's Niche 
> column of Bill
> Venables) and came up with:
> 
> > f <- lapply(e,function(x){do.call(substitute,list(x,list(b=z1)))})
> > f
> [[1]]
> [1] 0
> 
> [[2]]
> a * (1/t)
> 
> > ## f is a list. Turn it back into an expression
> > f <- as.expression(f)
> > ## check that this works as intended
> > f
> expression(0, a * (1/t))
> > a <- 2
> > t <- 3
> > eval(f)
> [1] 0.6666667
> 
> Now you'll note that to do this I explicitly used quote() to 
> produce the
> variable holding the subexpression to be substituted. You may 
> ask, why not
> use expression() instead, as in 
> 
> > z2 <- expression(1/t)
> 
> This doesn't work:
> 
> > f <- lapply(e,function(x){do.call(substitute,list(x,list(b=z2)))})
> > f
> [[1]]
> [1] 0
> 
> [[2]]
> a * expression(1/t)
> 
> > f <- as.expression(f)
> ## Yielding ...
> > f
> expression(0, a * expression(1/t)) #### Not what we want! 
> ## And sure enough ...
> > eval(f)
> Error in a * expression(1/t) : non-numeric argument to binary operator
> 
> I think I understand why the z <- expression() approach does 
> not work; but I
> do not understand why the z <- quote() approach does! The 
> mode of the return
> from both of these is "call", but they are different (because 
> identical()
> tells me so). Could someone perhaps elaborate on this a bit 
> more? And is
> there a yet simpler and more straightforward way to do the 
> above than what I
> proposed?
> 
> Cheers,
> 
> Bert Gunter
> Genentech Nonclinical Statistics
> 
> 
> -----Original Message-----
> From: r-help-bounces at r-project.org 
> [mailto:r-help-bounces at r-project.org] On
> Behalf Of Gabor Grothendieck
> Sent: Friday, January 29, 2010 11:01 AM
> To: Jennifer Young
> Cc: r-help at r-project.org
> Subject: Re: [R] evaluating expressions with sub expressions
> 
> The following recursively walks the expression tree.  The esub
> function is from this page (you may wish to read that entire thread):
> http://tolstoy.newcastle.edu.au/R/help/04/03/1245.html
> 
> esub <- function(expr, sublist) do.call("substitute", 
> list(expr, sublist))
> 
> proc <- function(e, env = parent.frame()) {
>    for(nm in all.vars(e)) {
>       if (exists(nm, env) && is.language(g <- get(nm, env))) {
>          if (is.expression(g)) g <- g[[1]]
>             g <- Recall(g, env)
>             L <- list(g)
>             names(L) <- nm
>              e <- esub(e, L)
> 	  }
>         }
>      e
> }
> 
> mat <- expression(0, f1*s1*g1)
> g1 <- expression(1/Tm)
> vals <- data.frame(f1=1, s1=.5, Tm=2)
> e <- sapply(mat, proc)
> sapply(e, eval, vals)
> 
> The last line should give:
> 
> > sapply(e, eval, vals)
> [1] 0.00 0.25
> 
> 
> On Fri, Jan 29, 2010 at 11:51 AM, Jennifer Young
> <Jennifer.Young at math.mcmaster.ca> wrote:
> > Hallo
> >
> > I'm having trouble figuring out how to evaluate an 
> expression when one of
> > the variables in the expression is defined separately as a 
> sub expression.
> > Here's a simplified example
> >
> > mat <- expression(0, f1*s1*g1)  # vector of formulae
> > g1 <- expression(1/Tm)          # expansion of the definition of g1
> > vals <- data.frame(f1=1, s1=.5, Tm=2) # one set of possible 
> values for
> > variables
> >
> > before adding this sub expression I was using the following 
> to evaluate
> "mat"
> >
> > sapply(mat, eval, vals)
> >
> > Obviously I could manually substitute in 1/Tm for each g1 in the
> > definition of "mat", but the actual expression vector is 
> much longer, and
> > the sub expression more complicated. Also, the 
> subexpression is often
> > adjusted for different scenarios.  Is there a simple way of 
> changing this
> > or redefining "mat" so that I can define "g1" like a macro 
> to be used in
> > the expression vector.
> >
> > Thanks!
> > Jennifer
> >
> > ______________________________________________
> > R-help at 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.
> >
> 
> ______________________________________________
> R-help at 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.
> 
> ______________________________________________
> R-help at 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.
> 



More information about the R-help mailing list