对 Ops 的通用方法进行分组用于时间序列

问题描述

我尝试在 S3 类上定义一个类 Ops 继承,该类是一个列表并且在列表中具有时间序列。

tsnewobject_a <- structure(list(data=ts(1:10,frequency=4,start=2010)),class="newclass")
tsnewobject_b <- structure(list(data=ts(10:1,class="newclass")

## Step 1 : with S3 only (note : I don't want to modify Ops.ts)

Ops.newclass <- function(e1,e2) {
  if (inherits(e1,"newclass")) e1 <- e1$data
  if (inherits(e2,"newclass")) e2 <- e2$data
  get(.Generic)(e1,e2)
}

tsnewobject_a+tsnewobject_b
#      Qtr1 Qtr2 Qtr3 Qtr4
# 2010   11   11   11   11
# 2011   11   11   11   11
# 2012   11   11 

# It works !

tsnewobject_a+1
#      Qtr1 Qtr2 Qtr3 Qtr4
# 2010    2    3    4    5
# 2011    6    7    8    9
# 2012   10   11 

# It works !

1+tsnewobject_a
#      Qtr1 Qtr2 Qtr3 Qtr4
# 2010    2    3    4    5
# 2011    6    7    8    9
# 2012   10   11 

# It works !

tsnewobject_a+ts(1:10,start=2010)
# Error in tsnewobject_a + ts(1:10,frequency = 4,start = 2010) : 
#   non-numeric argument to binary operator
# In addition: Warning message:
# Incompatible methods ("Ops.newclass","Ops.ts") for "+" 

# It doesn't work (it's expected)

ts(1:10,start=2010)+tsnewobject_a
# Error in ts(1:10,start = 2010) + tsnewobject_a : 
#   non-numeric argument to binary operator
# In addition: Warning message:
# Incompatible methods ("Ops.ts","Ops.newclass") for "+" 

# It doesn't work (it's expected)

由于 S3 双重调度,它不适用于简单的方法。因为我不想覆盖 Ops.ts(它是一个包),所以我必须找到一些东西。

## Step 2 : setoldClass to complete S3 with a small s4 fix

setoldClass("newclass")
setMethod("Ops",signature = c("newclass","ts"),function(e1,e2) callGeneric(e1$data,e2))
setMethod("Ops",signature = c("ts","newclass"),e2) callGeneric(e1,e2$data))

tsnewobject_a+ts(1:10,start=2010)

# Error in tsnewobject_a + ts(1:10,"Ops.ts") for "+" 

# Still doesn't work

ts(1:10,start=2010)+tsnewobject_a

# Error in ts(1:10,"Ops.newclass") for "+" 

# Still doesn't work

我觉得很奇怪,因为 Ops 是 S4 组通用的。它不应该调用可用的 S4 方法,然后,如果没有,则转到 S3 吗?会发生什么,如何修复?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)