[R] Tidiest way of modifying S4 classes?

Martin Maechler maechler at stat.math.ethz.ch
Tue Nov 15 10:42:33 CET 2005


>>>>> "PaCo" == Patrick Connolly <p.connolly at hortresearch.co.nz>
>>>>>     on Tue, 15 Nov 2005 09:58:31 +1300 writes:

    PaCo> I wish to make modifications to the plot.pedigree function in the
    PaCo> kinship package.  My attempts to contact the maintainer have been
    PaCo> unsuccessful, but my question is general, so specifics of the kinship
    PaCo> package might not be an issue.

well, but a quick look confirms that "pedigree" is an S3 class
and not a formal S4 one.  And, as the name  plot.pedigree
suggests, this is an S3 method for the 'plot' generic.

(And  ?plot.pedigree  shows a ``wrong'' usage, namely
 'plot.pedigree(.....)' instead of   'plot(..........)'
 because the authors didn't use the recommended
 \method{plot}{pedigree}(....)   syntax in their documentation
)

Unfortunately, the examples from the main help pages are not
executable either...  {and I'd vote to "forbid" that..}

After all my grumbling: 
The quick answer is: You'd have to redefine  plot.pedigree {no
new name!} in your own code and then call plot(<pedigree-object>, ...)
unless you really go for a new name such as 'Plot' {which would
need a 'Plot' generic and a 'Plot.pedigree' method}.
In your redefinition you may explicitly call  kinship:::plot.pedigree(..)
which might be useful.  
Because of the 'kinship' namespace protection,
note that  kinship-internal functions calling  plot(<pedigree>, ..)
or plot.pedigree(<pedigree>, ..)  will always call kinship:::plot.pedigree
and not your modified version.
There are ways around that as well, but we don't advertize them
much, because there's probably too much slicksand (aka "rope to
hang yourself") here...

Unfortunately, this has nothing to do with the niceties of S4
classes and methods.

Martin

    PaCo> My first attempt was to make a new function Plot.pedigree in the
    PaCo> .GlobalEnv which mostly achieved what I wanted to.  However, I'm sure
    PaCo> that's not the tidiest way to do it.  We don't have the green book,
    PaCo> but there's lots of interesting information I found here:

    PaCo> http://www.stat.auckland.ac.nz/S-Workshop/Gentleman/S4Objects

    PaCo> However, there's something I'm missing in connecting that information
    PaCo> into knowledge of how I go about making a new method or slot or
    PaCo> whatever is sensible in this case.  What does one make of this:


    >> getClass(class(kinship:::plot.pedigree))

    PaCo> No Slots, prototype of class "function"
          ^^^^^^^^

    PaCo> Extends: "OptionalFunction", "PossibleMethod"

    PaCo> Known Subclasses: 
    PaCo> Class "MethodDefinition", from data part
    PaCo> Class "genericFunction", from data part
    PaCo> Class "functionWithTrace", from data part
    PaCo> Class "derivedDefaultMethod", by class "MethodDefinition"
    PaCo> Class "MethodWithNext", by class "MethodDefinition"
    PaCo> Class "SealedMethodDefinition", by class "MethodDefinition"
    PaCo> Class "standardGeneric", by class "genericFunction"
    PaCo> Class "nonstandardGenericFunction", by class "genericFunction"
    PaCo> Class "groupGenericFunction", by class "genericFunction"

Here, simply

> class(kinship:::plot.pedigree)
[1] "function"

and getClass("function") treats it as an S4 class:
When the 'methods' package is loaded (as always per default),
many S3 classes are in some sense also S4 classes; this is
necessary such that  proper S4 classes can have slots containing
these S3 (i.e. "pseudo") classes.

    PaCo> If I want a new plot.pedigree function, do I make a slot, or what is
    PaCo> the approach to take?

(see above).

    PaCo> Suggestions most welcome.

    PaCo> Thanks

    PaCo> -- 
    PaCo> Patrick Connolly
    PaCo> HortResearch
    PaCo> Mt Albert
    PaCo> Auckland
    PaCo> New Zealand 
    PaCo> Ph: +64-9 815 4200 x 7188




More information about the R-help mailing list