Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

S3 Methods for Logical Operations

Tags:

r

Let's say that I have an S3 object:

obj <- list()
obj$A <- "This"
obj$B <- "That"
class(obj) <- "myclass"

How would I go about writing a method for myclass such that it referenced obj$B (for example) when I called it to create a logical vector

For example, I would like this behaviour:

obj == "That" # TRUE 
obj == "This" # FALSE

I'd like obj == "That" to return TRUE, but how do I tell == which part of the object to test?

How do I find documentation for this?

like image 604
Brandon Bertelsen Avatar asked Feb 10 '26 17:02

Brandon Bertelsen


1 Answers

You should consider writing an Ops.myclss method. It gives you the ability to handle all group methods in a single function.

See ?base::Ops, and methods(Ops) for example implementations. There's also a bit of information in Section 5.6 - Group Methods of R Language Definition.

Here's an example Ops.myclass that is a slightly modified version of Ops.Date:

Ops.myclass <-
function (e1, e2) 
{
    if (nargs() == 1) 
        stop(gettextf("unary %s not defined for \"myclass\" objects", 
            .Generic), domain = NA)
    boolean <- switch(.Generic, `<` = , `>` = , `==` = , `!=` = , 
        `<=` = , `>=` = TRUE, FALSE)
    if (!boolean) 
        stop(gettextf("%s not defined for \"myclass\" objects", 
            .Generic), domain = NA)
    if (inherits(e1, "myclass"))
        e1 <- e1$B
    if (inherits(e2, "myclass"))
        e2 <- e2$B
    NextMethod(.Generic)
}

Note that comparison will work whether or not e1 or e2 are myclass objects. And it will also work for any classes that extend myclass but do not define their own Ops method (though the error message would be confusing).

like image 134
Joshua Ulrich Avatar answered Feb 15 '26 06:02

Joshua Ulrich