当超类是“VIRTUAL”时,为什么我收到消息“节点堆栈溢出”?

时间:2013-05-04 14:49:53

标签: r s4

我收到了消息

parent.frame()中的错误:节点堆栈溢出 换行时出错:节点堆栈溢出

当我尝试使用S4命令“as”构建对象时,但当超类被声明为“VIRTUAL”时,

类层次结构如下:

PivotBasic包含Pivot包含模型

Pivot和Pivot Basic的setClass命令以及PivotBasic的构造函数如下所示。 Class Pivot没有构造函数。模型构造函数太大,无法在此处插入。

这真的不是什么大问题(我认为),因为如果从setClass的representation参数中删除“VIRTUAL”关键字,一切正常。但我很好奇这个问题的原因。有人会有这方面的见解吗?

谢谢,

Fernando Saldanha

setClass(Class = "Pivot", 
  representation = representation(
    pivotName = "character",
    pivotNames = "character",
    pivotData = "data.frame",
    "VIRTUAL"
  ),
  contains = "Model"
)

setClass(Class = "PivotBasic", 
  representation = representation(),
  contains = "Pivot"
)

pivotBasic <- function(
  portfolio,
  assets,

  controlVariableList,

  pivotData = NULL, # pivotName is ignored if pivotData is not null
  pivotName = "N_WEEKDAY_3_6",

  firstPredictionDate = as.Date(integer(), origin = "1970-01-01"),
  name = NULL,
  tags = "Event"
) {
  if (missing(portfolio)) stop("[PivotBasic: pivotBasic] - Missing portfolio argument")
  if (missing(assets)) stop("[PivotBasic: pivotBasic] - Missing assets argument")
  if (missing(controlVariableList)) stop("[PivotBasic: pivotBasic] - Missing controlVariableList argument")

  object <- model(
    portfolio,
    assets,
    controlVariableList,
    firstPredictionDate,
    name,
    tags)

  # The error message happens when this command is executed
  mdl <- as(object, "PivotBasic") 

  # Other code

  mdl
} # end pivotBasic

1 个答案:

答案 0 :(得分:1)

这是一个说明问题的最小例子

.Model <- setClass(Class = "Model",
  representation=representation(x="integer")
)

setClass(Class = "Pivot", 
  representation = representation("VIRTUAL"),
  contains = "Model"
)

.PivotBasic <- setClass(Class = "PivotBasic",
  contains = "Pivot"
)

这会产生错误

>     as(.Model(), "PivotBasic")
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
> R.version.string
[1] "R version 3.0.0 Patched (2013-04-15 r62590)"

但可能会生成错误,就像您在早期版本的R中看到的那样。thread on the R-devel mailing list是相关的,其中解决方案是定义setIs方法,例如

setIs("PivotBasic", "Model", 
  coerce = function(from) .PivotBasic(x = from@x), 
  replace = function(from, value) {
      from@x = value@x
      from
  }
)

我认为setIs是类定义的一部分。如果有许多插槽需要复制,那么在替换功能中可能会进一步解决这个问题

nms <- intersect(slotNames(value), slotNames(from))
for (nm in nms)
    slot(from, nm) <- slot(value, nm)
from

但潜在的问题实际上是在S4的实施中。取消“VIRTUAL”规范的成本是它会影响您的课堂设计,并且可能是S4系统的形式主义是您首先选择的动机;也许在面对替代方案时,成本并不是那么糟糕。