12

I have a S4 class and I would like to define the linear combination of these objects.

Is it possible to dispatch * and + functions on this specific class?

Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
RockScience
  • 17,932
  • 26
  • 89
  • 125

2 Answers2

16

The + operator is part of the Arith group generic (see ?GroupGenericFunctions) so one can implement all functions in the group with

setMethod("Arith", "yyy", function(e1, e2) {
    v = callGeneric(e1@v, e2@v)
    new("yyy", v = v)
})

and then with

setClass("yyy", representation(v="numeric"))
setMethod(show, "yyy", function(object) {
    cat("class:", class(object), "\n")
    cat("v:", object@v, "\n")
})
setMethod("Arith", "yyy", function(e1, e2) {
    v = callGeneric(e1@v, e2@v)
    new("yyy", v = v)
})

One would have

> y1 = new("yyy", v=1)
> y2 = new("yyy", v=2)
> y1 + y2
class: yyy 
v: 3 
> y1 / y2
class: yyy 
v: 0.5 
## ...and so on
Martin Morgan
  • 45,935
  • 7
  • 84
  • 112
  • Is that's assuming that you want to apply the + operator to all slots of the object? – RockScience Apr 18 '12 at 05:03
  • 1
    It is re-dispatching to the arithmetic operator for the slot 'v' of objects e1 and e2. If there were slots v and w, you might write for the body of the method `new("yyy", v = callGeneric(e1@v, e2@v), w = callGeneric(e1@w, e2@w))` – Martin Morgan Apr 18 '12 at 10:39
13

here is an example:

setClass("yyy", representation(v="numeric"))

setMethod("+", signature(e1 = "yyy", e2 = "yyy"), function (e1, e2) e1@v + e2@v)
setMethod("+", signature(e1 = "yyy", e2 = "numeric"), function (e1, e2) e1@v + e2)

then,

> y1 <- new("yyy", v = 1)
> y2 <- new("yyy", v = 2)
> 
> y1 + y2
[1] 3
> y1 + 3
[1] 4
kohske
  • 65,572
  • 8
  • 165
  • 155