Search code examples
roopr-s4

How to set a generic method which already exists in a used package?


I am modifying a S4-Class s4c and want to add a method index. Since the class is widely used in my custom package, renaming is no choice. Therefore I do

setGeneric(where = environment(), name="index", 
           def=function(x,include.from=T, include.to=T) standardGeneric("index")
           )
#' @export
setMethod(
  f = "index",
  signature = "s4c",
  definition = function (x, include.from, include.to) {
...

The method works. My problem is that I want to use the zoo-package also, where a generic function index already exists. If I load and attach the package I get the message

The following objects are masked by ‘.GlobalEnv’: index

and, suppose z to be a object of class zoo if I type index(zoo) I get the error

Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘index’ for signature ‘"zoo"’

Previously I worked with a more S3-like approach like

index.s4c <- function (x, include.from, include.to) {
...

and it worked. But I want to avoid this to get a 'pure' S4-class. My attempt to work with a local environment via where = environment() does not work. How to deal with this?

Many thanks, Mika


Solution

  • Use setGeneric to create an S4 generic index which uses the S3 generic as default as shown in the line marked ### below. Then test it out by creating a new class "A" with component x and an object of that class to test it out with:

    library(zoo)
    
    setGeneric("index") ###
    
    # test it out
    
    setClass("A", representation(x = "numeric"))
    setMethod("index", "A", function(x) x@x)
    a <- new("A", x = 99)
    index(a)      # index works on an object of our new class A
    ## [1] 99
    
    
    z <- zoo(100) # zoo object with value 100 and index 1
    index(z)      # index still works on zoo objects
    ## [1] 1