substitute, eval, bquote, do.call ... some guidance for substituting expressions
I would like to program a time series class. The idea is that I instantiate an object with an expression and some other time series objects, for instance
(two time series)
x <- ts(rnorm(10), frequency = 4, start = c(1959, 2))
y <- ts(rnorm(10), frequency = 4, start = c(1959, 2))
(a time series, defined to be the sum of x and y)
z <- exprTs("x+y", parents=list(x=x, y=y))
(get some part of the series)
window(z, start=1960, end=1960.75)
The problem is, how can I evaluate th开发者_JAVA百科e expression? I tried the following:
#(constructor for class)
exprTs <- function(expr, parents) {
res = list(expr=expr, parents=parents)
class(res) <- "exprTs"
res
}
#(window method)
window.exprTs <- function(z, ...) {
eval(substitute(z$expr, lapply(z$parents, window, ...)))
#do.call(z$expr, lapply(z$parents, window, ...))
}
I can not get the window method to work.
If you could guide me to how to use substitute, eval, do.call appropriately, that would be very helpful.
You may be thinking about this in the wrong way and just over-complicate things. There is already an addition defined for ts
objects:
R> set.seed(42)
R> x <- ts(rnorm(10), frequency = 4, start = c(1959, 2))
R> y <- ts(rnorm(10), frequency = 4, start = c(1959, 2))
R> z <- x + y
R> cbind(x,y,z)
x y z
1959 Q2 1.37096 1.3049 2.6758
1959 Q3 -0.56470 2.2866 1.7219
1959 Q4 0.36313 -1.3889 -1.0257
1960 Q1 0.63286 -0.2788 0.3541
1960 Q2 0.40427 -0.1333 0.2709
1960 Q3 -0.10612 0.6360 0.5298
1960 Q4 1.51152 -0.2843 1.2273
1961 Q1 -0.09466 -2.6565 -2.7511
1961 Q2 2.01842 -2.4405 -0.4220
1961 Q3 -0.06271 1.3201 1.2574
R>
You don't really need an expression parser to operate on R objects.
One problem is that you are specifying the expression as a string so it will be evaluated into a string. If you want to parse a string into an expression, you need to use the parse
command:
> "x+y"
[1] "x+y"
> parse(text="x+y")
expression(x+y)
attr(,"srcfile")
<text>
But yeah, why not use apply
and functions instead?
Now I found a solution:
window.exprTs <- function(z, ...) {
names(z$parents)<-NULL
do.call(z$expr, lapply(z$parents, window, ...))
}
plus <- function(x, ...) if (nargs() == 1) x else x + Recall(...)
z <- exprTs(plus, parents=list(x=x, y=y))
Now
window(z, start=1960, end=1960.75)
gives the desired result.
精彩评论