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.
Bert Gunter
2015-Nov-16 15:22 UTC
[R] Why does a custom function called is.numeric.factor break lattice?
There is no multiple dispatch; just multiple misunderstanding. The generic function is "is.numeric" . Your method for factors is "is.numeric.factor". You need to re-study. Cheers, Bert Bert Gunter "Data is not information. Information is not knowledge. And knowledge is certainly not wisdom." -- Clifford Stoll On Mon, Nov 16, 2015 at 5:00 AM, sbihorel <Sebastien.Bihorel at cognigencorp.com> wrote:> 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. > > >
Duncan Murdoch
2015-Nov-16 15:42 UTC
[R] Why does a custom function called is.numeric.factor break lattice?
On 16/11/2015 10:22 AM, Bert Gunter wrote:> There is no multiple dispatch; just multiple misunderstanding. > > The generic function is "is.numeric" . Your method for factors is > "is.numeric.factor". > > You need to re-study.I think the problem is with S3. "is.numeric.factor" could be a "numeric.factor" method for the "is" generic, or a "factor" method for the "is.numeric" generic. Using names with dots is a bad idea. This would be all be simpler and less ambiguous if the class had been named "numeric_factor" or "numericFactor" or anything without a dot. Duncan Murdoch