【问题标题】:substitute, eval, bquote, do.call ... some guidance for substituting expressions替换、评估、bquote、do.call ...替换表达式的一些指导
【发布时间】:2011-01-08 00:04:28
【问题描述】:

我想编写一个时间序列课程。这个想法是我用表达式和其他一些时间序列对象实例化一个对象,例如

(两个时间序列)

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)

问题是,我如何评估表达式?我尝试了以下方法:

#(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,那将非常有帮助。

【问题讨论】:

  • 为什么不直接使用已经属于zoorollapply 函数呢?这将满足您的需求。
  • 是的,也许这过于复杂了。但我想使用 exprTs 对象两次。首先是获取时间序列数据,其次是生成操作树和原始时间序列以用于文档记录。

标签: r time-series


【解决方案1】:

一个问题是您将表达式指定为字符串,因此它将被评估为字符串。如果要将字符串解析成表达式,需要使用parse命令:

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

但是,是的,为什么不使用 apply 和函数呢?

【讨论】:

  • 我还是不明白。替代(parse(text="x+y"), list(x=x, y=y)) 似乎不是产生总和的正确命令。
  • 您为什么要尝试替换而不是评估表达式? eval(parse(text="x+y")).
【解决方案2】:

您可能会以错误的方式思考这个问题,从而使事情变得过于复杂。已经为 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 对象进行操作。

【讨论】:

  • 是否可以动态定义函数,例如 z
  • 好的,我发现了 do.call("+", list(x=x,y=y))。仍在考虑使用两个以上的输入系列..
  • 在响应动态定义函数时,您的意思是 function(x, y) { x + y } ?
【解决方案3】:

现在我找到了解决方案:

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) 

给出想要的结果。

【讨论】:

  • 这样的事情会更容易吗? window
  • 感谢您提供此功能 减少我的注意!
猜你喜欢
相关资源
最近更新 更多
热门标签