R 实现组泛型 Ops() 以启用 S3 对象的比较

R implement group generics Ops() to enable comparison of S3 objects

我正在 R 中创建一个 S3 class,我希望能够对其进行 "<"">""==" 等比较。我相信我可以使用 Ops() 来实现这些,而不是与我所读到的 group generics 分开实现,但我还没有找到任何好的例子来说明如何做到这一点。

我只想说对于 myClass 我可以创建一个 as.integer.myClass() 函数,为了比较 ab 我可以先转换为整数:

if(as.integer(a) < as.integer(b)) foo

这完全可行,但我更愿意写

if(a < b) foo

我认为这行得通,但行不通:

Ops.myClass <- function(e1, e2) {
  Ops(as.integer(e1), as.integer(e2))
}
a < b
Error in (function (classes, fdef, mtable)  :
 unable to find an inherited method for function ‘Ops’ for signature ‘"integer", "integer"’ 

有什么帮助吗? 谢谢!

我对此的一般方法是使用 .Generic 并打开该方法。

Ops.myClass <- function(e1, e2)
{
  op = .Generic[[1]]
  switch(op,
         `<` = {
           print("called less than function")
           as.integer(e1) < as.integer(e2)
         },
         `>` = {
            print("called greater than function")
            as.integer(e1) > as.integer(e2)
         },
         stop("undefined operation")
  )
}

a <- 1
b <- 3
class(a) <- "myClass"
class(b) <- "myClass"


a > b
[1] "called greater than function"
[1] FALSE
a < b
[1] "called less than function"
[1] TRUE

请注意,Ops(my, my) 失败并出现相同的错误——您不是在调用 Ops,而是调用 Ops 组成员的泛型。所以获取泛型并在转换后的类型上调用它

Ops.my = function(e1, e2) get(.Generic)(as.integer(e1), as.integer(e2))

> my1 = structure(1:5, class="my")
> my2 = structure(5:1, class="my")
> my1 > my2
[1] FALSE FALSE FALSE  TRUE  TRUE
> my1 == my2
[1] FALSE FALSE  TRUE FALSE FALSE