I'd like to have a class A that computes a likelihood, and a subclass B
that computes the same likelihood by sometimes throws in an additional
term (B includes measurement error).
So B's likelihood needs to call A's, and then (sometimes) multiply by an
additional term.
It sounds as if, in the S3 scheme, NextMethod is supposed to do this:
like.A <- function(stuff) compute value
like.B <- function(stuff) extraFactor*NextMethod()
?
but, after some study of both the Language Manual (2.1) and the online
help of NextMethod I can't tell exactly what it does. In particular,
I'm not sure if it returns to the calling function, or how it decides
which flavor to call. The language manual says the method choice
depends on the values of .Generic and .Class, but doesn't say how those
get filled in. I would expect .Class to be the current class, in which
case the call is recursive. The online help says "'NextMethod'
invokes
the next method (determined by the class)" but it doesn't say how it is
determined. One ambiguity is whether "class" refers to the class (B)
or
the class attribute ("B", "A").
I think the documentation could be clearer.
Now, probably none of this matters to me, since several sources
(including the online help for S3)indicate that S4 classes are
preferred.
I found the documentation for S4 initially elusive. As far as I can
tell, it isn't even mentioned in the "R Language Definition."
While the
fact that S4 is defined in a package makes clear it is not formally part
of the base language, this is not a very good way to get people to use
S4.
I think by now I've tracked down docs on S4, including the
intro/overview at http://www.omegahat.org/RSMethods/.
Finally, I'm a bit concerned that one article mentioned that S4
inheritance, in practice, is used mostly for data, not methods (Thomas
Lumley, R News 4(1), June 2004: p. 36). Am I going down a road I
shouldn't travel?
--
Ross Boylan wk: (415) 502-4031
530 Parnassus Avenue (Library) rm 115-4 ross at biostat.ucsf.edu
Dept of Epidemiology and Biostatistics fax: (415) 476-9856
University of California, San Francisco
San Francisco, CA 94143-0840 hm: (415) 550-1062
Gabor Grothendieck
2005-May-23 22:09 UTC
[R] Documentation of S3 and S4 classes, inheritance
On 5/23/05, Ross Boylan <ross at biostat.ucsf.edu> wrote:> I'd like to have a class A that computes a likelihood, and a subclass B > that computes the same likelihood by sometimes throws in an additional > term (B includes measurement error). > > So B's likelihood needs to call A's, and then (sometimes) multiply by an > additional term. > > It sounds as if, in the S3 scheme, NextMethod is supposed to do this: > > like.A <- function(stuff) compute value > like.B <- function(stuff) extraFactor*NextMethod() > ?Here is a working example to try out. In the call to lik, the first class in the class vector is "B" so lik.B gets invoked. The next method of x is "A" so NextMethod invokes lik.A from within lik.B and then returns its result to lik.A which finishes the calculation. lik <- function(x) UseMethod("lik") lik.A <- function(x) mean(x) lik.B <- function(x) NextMethod("lik") + sd(x) x <- structure(1:3, class = c("B", "A")) lik(x) # 3> but, after some study of both the Language Manual (2.1) and the online > help of NextMethod I can't tell exactly what it does. In particular, > I'm not sure if it returns to the calling function, or how it decides > which flavor to call. The language manual says the method choice > depends on the values of .Generic and .Class, but doesn't say how those > get filled in. I would expect .Class to be the current class, in which > case the call is recursive. The online help says "'NextMethod' invokes > the next method (determined by the class)" but it doesn't say how it is > determined. One ambiguity is whether "class" refers to the class (B) or > the class attribute ("B", "A").See above discussion.> > I think the documentation could be clearer. > > Now, probably none of this matters to me, since several sources > (including the online help for S3)indicate that S4 classes are > preferred. > > I found the documentation for S4 initially elusive. As far as I can > tell, it isn't even mentioned in the "R Language Definition." While the > fact that S4 is defined in a package makes clear it is not formally part > of the base language, this is not a very good way to get people to use > S4. > > I think by now I've tracked down docs on S4, including the > intro/overview at http://www.omegahat.org/RSMethods/. > > Finally, I'm a bit concerned that one article mentioned that S4 > inheritance, in practice, is used mostly for data, not methods (Thomas > Lumley, R News 4(1), June 2004: p. 36). Am I going down a road I > shouldn't travel? >This area seems somewhat controversial with different people stating different opinions. IMHO you are probably best off to start with S3 since its simpler and if you do learn S4 later they are not unrelated so it will make it easier than jumping straight into it. Also you may find you never have to go beyond S3 in which case you have saved yourself some time. I personally use S3. By the way if choosing from S3 and S4 is not enough, there are also two CRAN packages that provide additional OO models as well: R.oo and proto.
On Mon, 2005-05-23 at 14:41 -0700, Ross Boylan wrote: ....> Finally, I'm a bit concerned that one article mentioned that S4 > inheritance, in practice, is used mostly for data, not methods (Thomas > Lumley, R News 4(1), June 2004: p. 36). Am I going down a road I > shouldn't travel? >Hmm, maybe I just found out. If B is an S4 subclass of A (aka extends A), how does B's method foo invoke A's foo? The question assumes that A's foo was defined as an in place function, so there's no (obvious) named object for it, i.e, setMethod("A", signature(blah="numeric"), function(x) something)