-----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
[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
f <- lapply(e,function(x){do.call(substitute,list(x,list(b=z2)))})
f
[[1]]
[1] 0
[[2]]
a * expression(1/t)
expression(0, a * expression(1/t)) #### Not what we want!
## And sure enough ...
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:
[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
the variables in the expression is defined separately as a
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
variables
before adding this sub expression I was using the following
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
the sub expression more complicated. Also, the
adjusted for different scenarios. ?Is there a simple way of
or redefining "mat" so that I can define "g1" like a macro
the expression vector.
Thanks!
Jennifer