2010-01-21 38 views
3

我想编程一个时间系列类。这个想法是,我实例用表达和一些其他的时间序列对象的对象,例如替代,eval,bquote,do.call ...替换表达式的一些指导

(两个时间序列)

x <- ts(rnorm(10), frequency = 4, start = c(1959, 2)) 
y <- ts(rnorm(10), frequency = 4, start = c(1959, 2)) 

(时间序列,定义为x和y的总和)

z <- exprTs("x+y", parents=list(x=x, y=y)) 

(获得系列的某些部分)

window(z, start=1960, end=1960.75) 

的问题是,我该怎么EVAL用表达?我尝试了以下内容:

#(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, ...)) 
} 

我无法获得窗口方法的工作。

如果你能指导我如何使用替代,eval,do.call适当的,这将是非常有益的。

+2

为什么不直接使用已经属于'zoo'的'rollapply'函数?这将做你需要的。 – Shane 2010-01-22 00:11:14

+0

是的,也许这是过度复杂。但是我想用两次exprTs对象。首先是获取时间序列数据,其次是产生一个操作树和原始时间序列树,用于文档目的。 – 2010-01-22 07:04:33

回答

5

一个问题是,您要将表达式指定为字符串,以便将其评估为字符串。如果你想将一个字符串解析成一个表达式,你需要使用parse命令:

> "x+y" 
[1] "x+y" 
> parse(text="x+y") 
expression(x+y) 
attr(,"srcfile") 
<text> 

但是,是的,为什么不使用apply和功能呢?

+0

我还是不明白。 替代(解析(text =“x + y”),列表(x = x,y = y)) 似乎不是产生总和的正确命令。 – 2010-01-22 07:00:25

+0

你为什么试图替代而不是评估表达? '的eval(解析(文本= “X + Y”))'。 – 2010-01-22 19:16:59

5

你可能会以错误的方式思考这个问题,并且会让事情变得过于复杂。已经有一个ts对象定义的加法:

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> 

你并不真的需要一个表达式解析器R上对象进行操作。

+0

是否有可能在飞行中定义一个功能,如 z < - do.call(make.function(x + y),list(x = x,y = y)) 我想延迟总和的计算。 – 2010-01-22 07:23:13

+0

好的,我发现了关于do.call(“+”,list(x = x,y = y))。仍然在考虑使用多于两个输入序列.. – 2010-01-22 12:07:18

+0

作为对即时定义函数的回应,您的意思是“function(x,y){x + y}'? – 2010-01-22 18:42:54

1

现在我找到了一个解决方案:

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)) 

现在

window(z, start=1960, end=1960.75) 

给出了期望的结果。

+1

这样会更容易吗? 窗口< - function(f,...){Reduce(f,list(...))} x < - rnorm(10); y < - rnorm(10); ž< - RNORM(10) 窗口( “+”,X,Y,Z) [1] 2.0518301 2.3578890 -1.4470385 0.1740018 -0.5145332 - 1.1365355 [7] 1.2252515 1.2743573 -0.1090204 2.1623625 – 2010-01-22 21:20:48

+0

感谢您将这一功能减少到我的注意力! – 2010-01-23 00:26:17