[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