Re: [R] evaluating expressions with sub expressions
Thanks so much everyone! Bert's shorted example does what I need, but I'm filing away Gabor's solution for when I inevitably need it some day. I've never found the handling of variables in R to be very straightforward; sometimes I pine for Maple to do my algebra for me... If its good enough to have one level of substitution then esub in my post (originally due to Tony Plate -- see reference in my post) is all that is needed: esub(mat[[2]], list(g1 = g1[[1]])) but I think the real problem could require multiple levels of substitution in which case repeated application of esub is needed as you walk the expression tree which is what proc() in my post does. For example, suppose mat[[2]] is a function of g1 which is a function of Tm which is a function of z. Then continuing the example in the original post this does the repeated substitution needed (which would be followed by an eval, not shown here, as in my original post): Tm - expression(z^2) sapply(mat, proc) [[1]] [1] 0 [[2]] f1 * s1 * (1/z^2) To answer your question, quote() produces a call object but expression produces a call wrapped in an expression which is why there is special handling of expression objects in the proc() function in my post. On Fri, Jan 29, 2010 at 4:38 PM, Bert Gunter gunter.ber...@gene.com wrote: 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.667 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
Re: [R] evaluating expressions with sub expressions
On Sat, Jan 30, 2010 at 10:39 AM, Jennifer Young jennifer.yo...@math.mcmaster.ca wrote: handling of variables in R to be very straightforward; sometimes I pine for Maple to do my algebra for me... There are several interfaces to Computer Algebra Systems in R. Try this (but read instructions on home page http://ryacas.googlecode.com first particularly the part about ensuring you have the right version of XML installed). Below, Sym creates a symbolic variable: library(Ryacas) Loading required package: XML f1 - Sym(f1) s1 - Sym(s1) Tm - Sym(Tm) g1 - 1/Tm mat - f1 * s1 * g1 mat [1] Starting Yacas! expression(f1 * s1/Tm) __ 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] evaluating expressions with sub expressions
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.
Re: [R] evaluating expressions with sub expressions
Hi, Would this do as an alternative syntax? g1 - quote(1/Tm) mat - list(0, bquote(f1*s1*.(g1))) vals - data.frame(f1=1, s1=.5, Tm=2) sapply(mat, eval, vals) HTH, baptiste On 29 January 2010 17:51, 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.
Re: [R] evaluating expressions with sub expressions
Hmm I *think* this will work, but may break in a further sub routine. It certainly works in this example, but my expression vector is used in many scenarios and it will take a while to check them all. For instance, I take the derivative of each element with respect to each variable using sapply(mat, deriv, names(vals)) This bit seems to still work, but I'd welcome a solution that doesn't change the structure of the expression vector to a list, just in case. Thanks for this solution. Hi, Would this do as an alternative syntax? g1 - quote(1/Tm) mat - list(0, bquote(f1*s1*.(g1))) vals - data.frame(f1=1, s1=.5, Tm=2) sapply(mat, eval, vals) HTH, baptiste On 29 January 2010 17:51, 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.
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.
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.667 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.
Re: [R] evaluating expressions with sub expressions
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.667 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
Re: [R] evaluating expressions with sub expressions
If its good enough to have one level of substitution then esub in my post (originally due to Tony Plate -- see reference in my post) is all that is needed: esub(mat[[2]], list(g1 = g1[[1]])) but I think the real problem could require multiple levels of substitution in which case repeated application of esub is needed as you walk the expression tree which is what proc() in my post does. For example, suppose mat[[2]] is a function of g1 which is a function of Tm which is a function of z. Then continuing the example in the original post this does the repeated substitution needed (which would be followed by an eval, not shown here, as in my original post): Tm - expression(z^2) sapply(mat, proc) [[1]] [1] 0 [[2]] f1 * s1 * (1/z^2) To answer your question, quote() produces a call object but expression produces a call wrapped in an expression which is why there is special handling of expression objects in the proc() function in my post. On Fri, Jan 29, 2010 at 4:38 PM, Bert Gunter gunter.ber...@gene.com wrote: 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.667 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
Re: [R] evaluating expressions with sub expressions
Inline below... -Original Message- From: Gabor Grothendieck [mailto:ggrothendi...@gmail.com] Sent: Friday, January 29, 2010 2:12 PM To: Bert Gunter Cc: Jennifer Young; r-help@r-project.org Subject: Re: [R] evaluating expressions with sub expressions If its good enough to have one level of substitution then esub in my post (originally due to Tony Plate -- see reference in my post) is all that is needed: esub(mat[[2]], list(g1 = g1[[1]])) --- Yes, this is essentially what I did using lapply but I think the real problem could require multiple levels of substitution in which case repeated application of esub is needed as you walk the expression tree which is what proc() in my post does. -- Indeed. But my point was to handle the simple case simply. To answer your question, quote() produces a call object but expression produces a call wrapped in an expression which is why there is special handling of expression objects in the proc() function in my post. -- Aha! And of course I should have realized that I could have easily determined this myself with: as.list(quote(a*b)) [[1]] `*` [[2]] a [[3]] b ## But ... e - as.list(expression(a*b)) e [[1]] a * b mode(e[[1]]) [1] call as.list(e[[1]]) [[1]] `*` [[2]] a [[3]] b So now all is clear to me. Thanks to both Bill and Gabor for their informative replies. -- Bert Bert Gunter Genentech Nonclinical Statistics On Fri, Jan 29, 2010 at 4:38 PM, Bert Gunter gunter.ber...@gene.com wrote: 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.667 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