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

*爱你&永不变心* 提交于 2019-12-24 00:27:21

问题


I am creating an S3 class in R for which I would like to be able to do comparisons like "<", ">", and "==". Rather than implement each of these separately from what I've read about group generics I believe I can do so using Ops() but I haven't found any good examples of how to do this.

Suffice it to say that for myClass I can create an as.integer.myClass() function, and that to compare a and b I could just convert to integer first:

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

This totally works, but I would so much rather write

if(a < b) foo

I thought this would work, but it doesn't:

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"’ 

Any help? Thanks!


回答1:


Note that Ops(my, my) fails with the same error -- you're not invoking Ops, but a generic that is a member of the Ops group. So get the generic and invoke it on the transformed types

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

with

> 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



回答2:


The general approach I have for this is to use .Generic and switch on the method.

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


来源:https://stackoverflow.com/questions/35902360/r-implement-group-generics-ops-to-enable-comparison-of-s3-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!