[R] Extending a group of S4 classes by setClassUnion ?

Martin Morgan mtmorgan at fhcrc.org
Thu Mar 15 17:36:13 CET 2012


Hi Alexander --

On 03/15/2012 07:57 AM, Alexander wrote:
> Hi,
> I would like to create some S4 classes as follows
>
> setClass("Father",representation(name="character"))
> setClass("Son1",contains="Father",representation(par="numeric"))
> setClass("Son2",contains="Father",representation(par="logical"))
>
> Son1<-new("Son1")
> Son1 at name<-"Son1"
> Son1 at par<-3

it's more efficient to call new("Son1", name="Son1", par=3)

> Son2<-new("Son2")
> Son2 at name<-"Son2"
> Son2 at par<-TRUE
>
> setGeneric("get.par",function(object){standardGeneric ("get.par")})

functions with '.' in their names can be confusing, because it could 
represent an S3 generic on 'get', for an S3 object of class 'par'.

> setMethod("get.par","Son1",function(object){return(object at par+3)})
> setMethod("get.par","Son2",function(object){return(!object at par)})
>
> get.par(Son1)
> get.par(Son2)
>
> So far, so good. I would like now, to create a new class, which
> "extends"/"contains" the subclasses of Father by some additional slots.
> Is there any clean and simple possibility to inherite also the corresponding
> function get.par ?
>
> setClass("Extension",representation(person="Father",text="character"))
> Ext<-new("Extension")
> Ext at text<-"new try"
> Ext at person<-Son1
> get.par(Ext)
> get.par(Ext at person)
>
> Of course, "get.par(Ext)" returns an error. Is there any possibility to tell
> R, that if now function exists for a Class, to transform the object to a
> class, for which the function exists ? (I know, it is not very clear what I
> am writing, but I am doing my best). I don't want to rewrite every method
> for  "Extension" like
>
> setMethod("get.par","Extension",function(object){get.par(object at person)})
>
> Is there any simpler solution by steClassUnion, setAs, setIs .... ?

You can provide an explicit relationship

setIs("Extension", "Father",
       coerce=function(from) from at person,
       replace=function(from, value) {
           from at person <- value
           from
       })

and then define a method on 'Father' (since that's what you're asserting 
equivalence to)

setMethod("get.par", "Father", function(object) object at name)

and finally have success with

ext <- new("Extension",
            person=new("Son1", name="Son1", par=3),
            text="new try")

 > get.par(ext)
[1] "Son1"

Neat, eh? But it really pays to ask whether the complexity of the class 
structure you're creating is appropriate for the solution that you need 
to implement -- imagine, for instance, writing a method that dispatches 
on two arguments, and as a programmer you need to implement appropriate 
methods for the tangle of dispatch that you have created.

Martin

>
> Thanks a lot in advance
>
> Alexander
>
> --
> View this message in context: http://r.789695.n4.nabble.com/Extending-a-group-of-S4-classes-by-setClassUnion-tp4475251p4475251.html
> Sent from the R help mailing list archive at Nabble.com.
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.


-- 
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793



More information about the R-help mailing list