[R] Overloading in R

Martin Morgan mtmorgan at fhcrc.org
Sun Feb 15 20:43:58 CET 2009


Hi Shrikanth --

SHRIKANTH SHANKAR <shrikanth.shankar at gmail.com> writes:

> I have been trying to write a new class that reimplements the vector
> class. As a test of my overloading I decided to try and and call
> t.test on two vectors which were objects of my class rather than the
> default class.
>
> The  overloaded length I wrote seems to work correctly. I used
> setMethod("length", "myvector", ...)
> setMethod("mean", "myvector", ...)
> setMethod("var", "myvector", ...)
>
> and created an object
>
> myv <- new("myvector",...)
>
> and when I called t.test(myv, myv)
> it first failed in the line
>
> mx <- mean(x)
>
> with the error that "x is not atomic
>
> I finally worked around by doing
>
> "mean.myvector" <- function(x, ...) {

You're right in the diagnosis that generics are not defined for all
functions. This is true in both the 'S3' and 'S4' class systems.

A very conservative approach would program as though 'vector' and its
descendants were primitives that have functions that cannot be
overloaded, just as methods cannot be defined on primitive 'int' in
Java -- an S4 object will never 'be a' numeric, but might 'have a'
numeric slot. Instead use methods defined on your class to describe
the API you want -- e.g., setGeneric('t.test'); setMethod(t.test,
"myvector", ...) if that is relevant.

Another common approach is to extend vector-like classes and to define
an API that gives desirable properties for your class, but reverts to
'built-in' behavior otherwise --

> setClass("Numeric", "numeric")
[1] "Numeric"
> x <- new("Numeric", 1:10)
> x[1:5] # 'class' preserved across subset
An object of class "Numeric"
[1] 1 2 3 4 5
> mean(x) # operation on numeric data, 'unaware' of class
[1] 5.5
> # define an API
> Numeric <- function(x, ...) new("Numeric", x, ...)
> setGeneric("mean")
[1] "mean"
> setMethod("mean", "Numeric", function(x, ...) Numeric(mean(x at .Data)))
[1] "mean"
> mean(x)
An object of class "Numeric"
[1] 5.5
> # revert to built-in behavior for at least some operations...
> t.test(v)

	One Sample t-test

data:  v 
...

mean.myvector mixes S3 and S4 systems, and should be avoided.

getGeneric() can be useful to find what the generic looks like, if it
does exist; setGeneric makes a non-generic function generic, but this
will not likely be useful in the present case (R has the notion of a
name space; setGeneric defines a generic in the current, e.g., global,
name space, whereas a function might look for the function in a
different place).

Hope that helps,

Martin

> I now get the same error in the next line
>
> vx <- var(x)
>
> I tried doing
> "var.myvector" <- function(x,....) as well as
> "var.myvector" <- function(x, y=NULL, na.rm=FALSE, use)
>
> all to no luck
>
> from within R I see the following
>
>> showMethods("var")
>
> Function "var":
>  <not a generic function>
>> var
> function (x, y = NULL, na.rm = FALSE, use)
> {
> ..
> }
> <environment: namespace:stats>
>
> I *think* I understand that this has something to do with the fact
> that no generic function is declared for var so my function is not
> getting dispatched but with my limited knowledge of R I wasnt able to
> get setGeneric to work...
>
> Any suggestions?
>
> Apologies if this is answered somewhere else.
>
> Thanks,
> Shrikanth
>
> ______________________________________________
> 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.

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

Location: Arnold Building M2 B169
Phone: (206) 667-2793




More information about the R-help mailing list