[R] overloading the generic primitive functions "+" and "["

Martin Morgan mtmorgan at fhcrc.org
Thu Oct 28 15:12:31 CEST 2010


On 10/28/2010 02:17 AM, Barry Rowlingson wrote:
> On Thu, Oct 28, 2010 at 9:31 AM, Mark Heckmann <mark.heckmann at gmx.de> wrote:
>>
>> How can I add a new method to the generic function "[" or "+"
>>
>> I want to create a S3 and S4 class that will use the "[" and "+" method in a different way.
>> How can I overload the generic primitive "[" or "+" so the method dispatch will work correctly for my class?
>>
>> I saw an example of this in the ggplot2 package where different objects are joined using the "+" primitive.
>> Still, I could not figure out how to do that.
>>
>> Can someone give a small code example to show how that works?
> 
>  With S3 method stuff, to override "+" its as easy as writing Ops.{class}:
> 
>  > a="hello"
>  > b="world"
>  > a+b
>  Error in a + b : non-numeric argument to binary operator
>  > class(a)="ss"
>  > class(b)="ss"
>  > Ops.ss=function(e1,e2){paste(e1,e2)}
>  > a+b
>  [1] "hello world"
> 
>  better make sure I haven't broken anything:
> 
>  > c=1
>  > d=2
>  > c+d
>  [1] 3   *phew*
> 
> The Ops function should really have a handler for all possible
> operators (*, /, - etc) or fail with an error - see Ops.Date for
> example.
> 
> With S4 classes... umm.. signatures... setMethod... setGeneric...
> errr. something... representations... setClass this that... yeah.
> Something like that.

The more-or-less literal translation of your S3 to S4 is

setClass("SS", "character")
setMethod(Ops, c("SS", "SS"), function(e1, e2) paste(e1, e2))

Not so hard, eh? Though then like your S3 implementation this makes all
'Ops' (see ?Ops) the same for SS objects. For "+" alone

setMethod("+", c("SS", "SS"), function(e1, e2) paste(e1, e2))

One might typically use a group generic like Ops (or Arith for a narrow
set of operations in S4) when wanting to delegate to a slot of a class,
e.g.,

setClass("Person", representation(age="numeric"))
setMethod(Arith, c("Person", "Person"), function(e1, e2) {
    callGeneric(e1 at age, e2 at age)
})

> Phred = new("Person", age=32)
> Phrank = new("Person", age=37)
> Phred - Phrank
[1] -5
> Phred * Phrank
[1] 1184

Martin

> 
> Barry
> 
> ______________________________________________
> 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