andrechalom
andrechalom

Reputation: 737

Is it possible to redefine an S4 class in R?

I am working on a package that extends another package, and both of them use S4 classes and methods. More specifically, I'm working on the sads package, that extends Ben Bolker's bbmle. Our full source code is here: https://github.com/piLaboratory/sads

So far, I have successfully created new classes that extend the mle2 S4 class from the package bbmle. These lines do it nicely:

setClass("fitsad", representation("mle2", sad="character", 
  distr="character", trunc="numeric"))
setClass("fitrad", representation("mle2", rad="character", 
  distr="character", trunc="numeric", rad.tab="rad"))

However, I'm not being able to cleanly redefine a class that was defined in bbmle. The class summary.mle2 is defined in the source code for bbmle, but let's pretend that I need to define a new class with the same name. Adding the following line to my source code results in a weird behavior:

setClass("summary.mle2", representation(call = "language", 
  coef = "matrix",m2logL = "numeric", fixed="numeric"))

With this redefinition, the package can be loaded, and all the code works as expected. However, trying to unload the namespace results in the following cryptic error:

> library(sads) ## No errors here
> unloadNamespace("sads")
Error in .getClassFromCache(what, resolve.confl = "all") : 
 argument "where" is missing, with no default
> traceback()
4: .getClassFromCache(what, resolve.confl = "all")
3: .removeSuperclassBackRefs(cl, cldef, searchWhere)
2: methods::cacheMetaData(ns, FALSE, ns)
1: unloadNamespace("sads")

Leaving aside the question of whether we should be redefining this class or not, is this possible to do? I am sorry for not being able to present a minimal example here, but I haven't been able to reproduce this error without loading/unloading the package namespace.

Upvotes: 1

Views: 159

Answers (1)

sconfluentus
sconfluentus

Reputation: 4993

Ripped from the headlines of r{base}

setAs(from, to, def, replace, where = topenv(parent.frame()))

You can use this to coerce from an S4 to an S3 class

if you type ?setAs() in the help line it should get you 90% of the way there! You can use class() to see if it works!

Let me know if it works for you. If you get stuck then I will do my best to help you out.

Upvotes: 2

Related Questions