I have encountered a snippet of code where call contains another call. For example:
a <- 1
b <- 2
# First call
foo <- quote(a + a)
# Second call (call c
I came up with a simple solution to this, but it seems a little improper and I hope that a more canonical method exists to cope with this situation. Nevertheless, this should hopefully get the job done.
The basic idea is to iterate through your expression and replace the un-evaluated first call with its evaluated value. Code below:
a <- 1
b <- 2
# First call
foo <- quote(a + a)
# Second call (call contains another call)
bar <- quote(foo ^ b)
bar[[grep("foo", bar)]] <- eval(foo)
eval(bar)
#> [1] 4
So far this is pretty easy. Of course if your expressions are more complicated this becomes more complicated quickly. For instance, if your expression has foo^2 + a
then we need to be sure to replace the term foo^2
with eval(foo)^2
and not eval(foo)
and so on. We can write a little helper function, but it would need a good deal of work to robustly generalize to complexly nested cases:
# but if your expressions are more complex this can
# fail and you need to descend another level
bar1 <- quote(foo ^ b + 2*a)
# little two-level wrapper funciton
replace_with_eval <- function(call2, call1) {
to.fix <- grep(deparse(substitute(call1)), call2)
for (ind in to.fix) {
if (length(call2[[ind]]) > 1) {
to.fix.sub <- grep(deparse(substitute(call1)), call2[[ind]])
call2[[ind]][[to.fix.sub]] <- eval(call1)
} else {
call2[[ind]] <- eval(call1)
}
}
call2
}
replace_with_eval(bar1, foo)
#> 2^b + 2 * a
eval(replace_with_eval(bar1, foo))
#> [1] 6
bar3 <- quote(foo^b + foo)
eval(replace_with_eval(bar3, foo))
#> [1] 6
I thought I should somehow be able to do this with substitute()
but couldn't figure it out. I'm hopeful a more authoritative solution emerges but in the meantime this may work.