“Ops”组通用方法和match.call用于延迟评估

时间:2013-11-20 00:17:35

标签: r

我正在使用自定义指标语法语言(ISL)来设计和评估交易规则。

我想为自定义类indicator定义基本的二元运算符方法。 indicator上的操作,例如>=<=等,一旦评估,将具有二进制输出(零或一),存储在类signal的另一个对象中。 signal对象还应该包含延迟评估的操作定义(未评估的表达式)。

我的尝试:

### define classes

indicator <- function ()  {
  structure(NULL, class="indicator")
}

signal <- function (definition)  {
  structure(NULL, call=definition, class="signal")
}

`Ops.indicator` <- function(x, y, ...) {
  .call <- match.call()
  ret <- signal(definition=.call)
}

### create unevaluated definitions of indicators and signals

ind <- indicator()
sig <- ind <= 2

对象str(sig)的结构是:

 list()
 - attr(*, "call")= language Ops.indicator(x = ind, y = 2)
 - attr(*, "class")= chr "signal"

而我需要使用<=存储特定表达式,以便稍后进行评估:

 list()
 - attr(*, "call")= language `<=.indicator`(x = ind, y = 2)
 - attr(*, "class")= chr "signal"

如何重写Ops.indicator来实现这一目标,而无需在“==”,“!=”,“&lt;”,“&lt; =”,“&gt;的6个独立指标方法中重复代码; =“,”&gt;“?

1 个答案:

答案 0 :(得分:3)

我这样做:

indicator <- function ()  {
  structure(list(), class="indicator")
}

binary_op <- function(op, x, y)  {
  structure(list(op = op, x = x, y = y), class = "binary_signal")
}

`Ops.indicator` <- function(x, y, ...) {
  binary_op(.Generic, substitute(x), substitute(y))
}

ind <- indicator()
sig <- ind <= 2

关键是使用特殊的.Generic值,但我还做了一些其他的小调整:

  • 如果基于列表元素而非属性

  • ,您会发现S3对象更容易使用
  • NULL是一个单例,因此为其分配属性会以静默方式将其强制转换为list()

  • 我认为如果存储单个部分而不是完整的呼叫,对象可能更容易使用。

最后,您可能希望详细了解domain specific languages in R