[R] overloading the generic primitive functions + and [

2010-10-28 Thread Mark Heckmann

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?

TIA
Mark

–––
Mark Heckmann
Dipl. Wirt.-Ing. cand. Psych.
Vorstraße 93 B01
28359 Bremen
Blog: www.markheckmann.de
R-Blog: http://ryouready.wordpress.com





[[alternative HTML version deleted]]

__
R-help@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.


Re: [R] overloading the generic primitive functions + and [

2010-10-28 Thread Barry Rowlingson
On Thu, Oct 28, 2010 at 9:31 AM, Mark Heckmann mark.heckm...@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.

Barry

__
R-help@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.


Re: [R] overloading the generic primitive functions + and [

2010-10-28 Thread Christofer Bogaso
Dear Barry, this is really interesting. However I could not understand
this line:

Ops.ss=function(e1,e2){paste(e1,e2)}

Where you have told R to behave + function differently when it faces
ss class?
What should be the ideal approach if I what to use * function?

Thanks,

On Thu, Oct 28, 2010 at 2:47 PM, Barry Rowlingson
b.rowling...@lancaster.ac.uk wrote:
 On Thu, Oct 28, 2010 at 9:31 AM, Mark Heckmann mark.heckm...@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.

 Barry

 __
 R-help@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.


__
R-help@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.


Re: [R] overloading the generic primitive functions + and [

2010-10-28 Thread Martin Morgan
On 10/28/2010 02:17 AM, Barry Rowlingson wrote:
 On Thu, Oct 28, 2010 at 9:31 AM, Mark Heckmann mark.heckm...@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(e...@age, e...@age)
})

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

Martin

 
 Barry
 
 __
 R-help@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

__
R-help@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.


Re: [R] overloading the generic primitive functions + and [

2010-10-28 Thread Barry Rowlingson
On Thu, Oct 28, 2010 at 2:12 PM, Martin Morgan mtmor...@fhcrc.org wrote:

 Not so hard, eh? Though then like your S3 implementation this makes all
 'Ops' (see ?Ops)

 Except you have to re-run the set* things every R session:

  setClass(SS, character)
  setMethod(Ops, c(SS, SS), function(e1, e2) paste(e1, e2))
  a=new(SS,hello)
  b=new(SS,world)
  a+b
 [1] hello world
  q()
 Save workspace image? [y/n/c]: y

...start R again...

[Previously saved workspace restored]

  a=new(SS,hello)
  b=new(SS,world)
  a+b
 Error in a + b : non-numeric argument to binary operator

 It seems the SS class is preserved but the method definition isn't.
Otherwise new(SS,hello) fails.

 That's one of the things that confuses me about S4 - its use of
invisible global things. ls(all.names=TRUE) shows me the bits:

  ls(all.names=TRUE)
 [1] a  .__C__SS   .requireCachedGenerics

 It seems that .__C__SS is the class definition, and the
.requireCachedGenerics seems to imply I've done something with 'Ops':

  .requireCachedGenerics
[[1]]
[1] Ops

 but doesn't actually store and restore my definition.

 A bug? I dunno. Version 2.10.1 if anyone cares. I don't. I'll just go
back to my S3 method which is just as simple and works when I restore
the .RData I saved things to. Each to their own!


Barry

__
R-help@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.


Re: [R] overloading the generic primitive functions + and [

2010-10-28 Thread Barry Rowlingson
On Thu, Oct 28, 2010 at 12:14 PM, Christofer Bogaso
bogaso.christo...@gmail.com wrote:
 Dear Barry, this is really interesting. However I could not understand
 this line:

 Ops.ss=function(e1,e2){paste(e1,e2)}

 Where you have told R to behave + function differently when it faces
 ss class?
 What should be the ideal approach if I what to use * function?

 You can get the character string of the operator from '.Generic', for example:

Ops.ss=function(e1,e2){
   if(.Generic==+){
return(paste(e1,e2))
   }
   if(.Generic==*){
 return(rep(e1,e2))
   }
  stop(No definition for ,.Generic)
}

Giving:

  a*5
 [1] hello hello hello hello hello
  a+world
 [1] hello world
  a/2
 Error in Ops.ss(a, 2) : No definition for /

Note how S3 methods are dispatched only by reference to the first
argument (on the left of the operator). I think S4 beats this by
having signatures that can dispatch depending on both arguments.

Barry

__
R-help@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.


Re: [R] overloading the generic primitive functions + and [

2010-10-28 Thread Hadley Wickham
 Note how S3 methods are dispatched only by reference to the first
 argument (on the left of the operator). I think S4 beats this by
 having signatures that can dispatch depending on both arguments.

That's somewhat of a simplification for primitive binary operators. R
actually looks up the method for both input classes, and returns a
error if they are different.

Hadley

-- 
Assistant Professor / Dobelman Family Junior Chair
Department of Statistics / Rice University
http://had.co.nz/

__
R-help@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.