rr-s3

How to override the implementation of a non-generic function in R


In R, I have an S3 class that emulates a 1D vector, and so I want to implement custom versions of mean, sum, max, etc. Let's say it looks like this:

my_class = function(){
  structure(list(), class='my_class')
}

All the above methods work fine, if I define mean.my_class etc:

mean.my_class = function(x){
  2
}

mean(my_class())

However, I would also like to do this for functions like var, which isn't a generic method. If I create such a function, and then call var on an instance of my class:

var.my_class = function(his){
  # Do stuff here
}

var(my_class())

I get the error:

Error in var(my_class()) : is.atomic(x) is not TRUE

This is because there is no generic var function, and it's just calling stats::var on my structure. How then can I provide a custom implementation if there isn't a generic method? I don't want to break the var method for regular vectors either.


Solution

  • From methods for non generics, S4 setMethod seems to be compatible with S3 class:

    setMethod("var","my_class",function(x, y = NULL, na.rm = FALSE, use) {"Var for my_class"})
    #> Creating a generic function for 'var' from package 'stats' in the global environment
    #> in method for 'var' with signature '"my_class"': no definition for class "my_class"
    
    my_class = function(){
      structure(list(), class='my_class')
    }
    
    var(my_class())
    #> [1] "Var for my_class"
    var(1:10)
    #> [1] 9.166667