[R] overloading the generic primitive functions + and [
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 [
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 [
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 [
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 [
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 [
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 [
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.