sbihorel
2015-Nov-16 02:22 UTC
[R] Why does a custom function called is.numeric.factor break lattice?
Hi, Pretty much everything is in the title of the post. An example is below. library(lattice) data <- data.frame(x=rep(1:10,8),y=rnorm(80),trt=factor(rep(1:4,each=20)),groups=rep(1:8,each=10)) xyplot <- xyplot(y~x|trt,data,groups=groups) is.numeric.factor <- function(){ print('hello world') } xyplot <- xyplot(y~x|trt,data,groups=groups) Thanks for shedding some light on this.
Bert Gunter
2015-Nov-16 02:42 UTC
[R] Why does a custom function called is.numeric.factor break lattice?
Think about it. I shall assume that you are familiar with S3 methods. What do you think would happen when xyplot code calls is.numeric() on a factor object expecting it to call the is.numeric primitive but, instead, finding a factor method defined, calls that? Note that your factor method has no arguments, but the is.numeric() primitive does. Hence when the code calls the primitive on the factor object, the error you saw is thrown. I would say that this is a weakness of the informal S3 "class" system, although you probably should not have been surprised that is.numeric is called on factors as the "x" argument, so you were inviting trouble by defining a factor method that overrides this behavior. Nevertheless, I would argue that one cannot know in general when this occurs for other S3 classes, and that therefore allowing methods for is.numeric() is dangerous. Of course, full qualification in the original xyplot code (base::is.numeric() rather than is.numeric() ) would avoid such things, but that's a drag. Contrary opinions and corrections to any flawed understanding on my part are welcome, of course. Cheers, Bert Bert Gunter "Data is not information. Information is not knowledge. And knowledge is certainly not wisdom." -- Clifford Stoll On Sun, Nov 15, 2015 at 6:22 PM, sbihorel <Sebastien.Bihorel at cognigencorp.com> wrote:> Hi, > > Pretty much everything is in the title of the post. An example is below. > > library(lattice) > data <- > data.frame(x=rep(1:10,8),y=rnorm(80),trt=factor(rep(1:4,each=20)),groups=rep(1:8,each=10)) > xyplot <- xyplot(y~x|trt,data,groups=groups) > > is.numeric.factor <- function(){ > print('hello world') > } > > xyplot <- xyplot(y~x|trt,data,groups=groups) > > Thanks for shedding some light on this. > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > 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.
Jeff Newmiller
2015-Nov-16 02:56 UTC
[R] Why does a custom function called is.numeric.factor break lattice?
You need to read about S3 classes, and either make your custom function behave the way that function needs to behave or use a different function name for your custom function. I think this is an example of the old saying that if it hurts when you slam your head against the wall, then don't do that. --------------------------------------------------------------------------- Jeff Newmiller The ..... ..... Go Live... DCN:<jdnewmil at dcn.davis.ca.us> Basics: ##.#. ##.#. Live Go... Live: OO#.. Dead: OO#.. Playing Research Engineer (Solar/Batteries O.O#. #.O#. with /Software/Embedded Controllers) .OO#. .OO#. rocks...1k --------------------------------------------------------------------------- Sent from my phone. Please excuse my brevity. On November 15, 2015 6:22:42 PM PST, sbihorel <Sebastien.Bihorel at cognigencorp.com> wrote:>Hi, > >Pretty much everything is in the title of the post. An example is >below. > >library(lattice) >data <- >data.frame(x=rep(1:10,8),y=rnorm(80),trt=factor(rep(1:4,each=20)),groups=rep(1:8,each=10)) >xyplot <- xyplot(y~x|trt,data,groups=groups) > >is.numeric.factor <- function(){ > print('hello world') >} > >xyplot <- xyplot(y~x|trt,data,groups=groups) > >Thanks for shedding some light on this. > >______________________________________________ >R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >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.
sbihorel
2015-Nov-16 13:00 UTC
[R] Why does a custom function called is.numeric.factor break lattice?
Hi, Interesting, based upon my understanding of S3 methods, I would have assumed that my function would be applied to objects of class "numeric.factor". I was not aware of this multiple "dispatch". Thanks for pointing this out. On 11/15/2015 9:42 PM, Bert Gunter wrote:> Think about it. > > I shall assume that you are familiar with S3 methods. What do you > think would happen when xyplot code calls is.numeric() on a factor > object expecting it to call the is.numeric primitive but, instead, > finding a factor method defined, calls that? Note that your factor > method has no arguments, but the is.numeric() primitive does. Hence > when the code calls the primitive on the factor object, the error you > saw is thrown. > > I would say that this is a weakness of the informal S3 "class" system, > although you probably should not have been surprised that is.numeric > is called on factors as the "x" argument, so you were inviting trouble > by defining a factor method that overrides this behavior. > Nevertheless, I would argue that one cannot know in general when this > occurs for other S3 classes, and that therefore allowing methods for > is.numeric() is dangerous. > > Of course, full qualification in the original xyplot code > (base::is.numeric() rather than is.numeric() ) would avoid such > things, but that's a drag. > > Contrary opinions and corrections to any flawed understanding on my > part are welcome, of course. > > Cheers, > Bert > > > Bert Gunter > > "Data is not information. Information is not knowledge. And knowledge > is certainly not wisdom." > -- Clifford Stoll > > > On Sun, Nov 15, 2015 at 6:22 PM, sbihorel > <Sebastien.Bihorel at cognigencorp.com> wrote: >> Hi, >> >> Pretty much everything is in the title of the post. An example is below. >> >> library(lattice) >> data <- >> data.frame(x=rep(1:10,8),y=rnorm(80),trt=factor(rep(1:4,each=20)),groups=rep(1:8,each=10)) >> xyplot <- xyplot(y~x|trt,data,groups=groups) >> >> is.numeric.factor <- function(){ >> print('hello world') >> } >> >> xyplot <- xyplot(y~x|trt,data,groups=groups) >> >> Thanks for shedding some light on this. >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> 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.