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-boun...@r-project.org > [mailto:r-help-boun...@r-project.org] On Behalf Of Bert Gunter > Sent: Friday, January 29, 2010 1:38 PM > To: 'Gabor Grothendieck'; 'Jennifer Young' > Cc: r-help@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-boun...@r-project.org > [mailto:r-help-boun...@r-project.org] On > Behalf Of Gabor Grothendieck > Sent: Friday, January 29, 2010 11:01 AM > To: Jennifer Young > Cc: r-help@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.yo...@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@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@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@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@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.