[R] Math ops behaviour with multiple classes

Jeff Newmiller jdnewmil at dcn.davis.ca.us
Fri Jun 9 02:46:27 CEST 2017


Cole, that cow left the barn decades ago. 

You really should read Patrick Burns' discussion of the history of R [1].

[1] http://www.burns-stat.com/documents/presentations/inferno-ish-R/
-- 
Sent from my phone. Please excuse my brevity.

On June 8, 2017 3:48:23 PM PDT, "Beck, Cole" <cole.beck at Vanderbilt.Edu> wrote:
>Thanks Bert, I think we agree on the current behaviour, but I'm still
>not sure if it's desirable.  The mode isn't used for method dispatch. 
>In the following example, I have to write `log.foo` in order for the
>correct method to be called.
>
>> x <- seq.int(5)
>> class(x) <- c("integer", "foo")
>> half <- function(x) UseMethod("half")
>> half.default <- function(x) {
>+   floor(x) / 2
>+ }
>> half.integer <- function(x) {
>+   x %/% 2
>+ }
>> half(log(x)) # dispatches half.integer, not desired
>[1] 0 0 0 0 0
>attr(,"class")
>[1] "integer" "foo"    
>> half(log(seq(5))) # dispatches half.default, as desired
>[1] 0.0 0.0 0.5 0.5 0.5
>> log.foo <- function(x) {
>+   res <- log(as.numeric(x))
>+   class(res) <- c("numeric", "foo")
>+   res
>+ }
>> half(log(x)) # dispatches log.foo, then half.default, as desired
>[1] 0.0 0.0 0.5 0.5 0.5
>attr(,"class")
>[1] "numeric" "foo"    
>
>Not only would I have to write `log.foo`, but I'd need to add my own
>`foo` methods for the Math and Ops groups.  Using a different class
>system might be a better solution, but my preference would definitely
>be for the base functions to coerce the class to numeric (which it
>indeed does if there are not multiple classes).
>
>Cole
>________________________________________
>From: Bert Gunter [bgunter.4567 at gmail.com]
>Sent: Thursday, June 08, 2017 4:45 PM
>To: Beck, Cole
>Cc: R-help
>Subject: Re: [R] Math ops behaviour with multiple classes
>
>I think you may be confusing (S3) class and ?mode.
>
>> x <- seq.int(1:3)
>> class(x)
>[1] "integer"
>> mode(x)
>[1] "numeric"
>> class(x+.5) ## coercion
>[1] "numeric"
>> mode(x+.5)
>[1] "numeric"
>
>But note:
>
>> y <- as.integer(1)
>> class(y)
>[1] "integer"
>> class(y) <- "foo"
>> mode(y)
>[1] "numeric"
>> class(y+.5)
>[1] "foo"
>> mode(y+.5)
>[1] "numeric"
>
>And further:
>
>> class(y) <-c("foo","integer")
>> class(y+.5)
>[1] "foo"     "integer"
>
>So basically, the behavior seems to be: when the class attribute can
>be coerced to "numeric" by as.numeric(), it is. Otherwise it is left
>as is.
>
>Note that log is a primitive function not in the Ops groups, but has
>similar behavior.
>
>I would guess (corroboration or correction by more knowledgeable folks
>appreciated!) that this sort of semi-confusion with S3 classes was one
>of the motivators for adding the more rigorous S4 system.
>
>HTH
>
>Cheers,
>Bert
>
>
>Bert Gunter
>
>"The trouble with having an open mind is that people keep coming along
>and sticking things into it."
>-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
>
>
>On Thu, Jun 8, 2017 at 9:40 AM, Cole Beck <cole.beck at vanderbilt.edu>
>wrote:
>> I would expect that several math operations should always return
>values with
>> a class of numeric.  If the input is defined with multiple classes,
>however,
>> the class attribute is preserved.  I would think this may have some
>> unintended side-effects.  Here's an example:
>>
>>> sessionInfo()$R.version$version.string
>> [1] "R version 3.4.0 (2017-04-21)"
>>> x <- seq.int(5)
>>> class(x)
>> [1] "integer"
>>> class(log(x))
>> [1] "numeric"
>>> class(x) <- c("integer", "foo")
>>> log(x)
>> [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379
>> attr(,"class")
>> [1] "integer" "foo"
>>> x + 0.5
>> [1] 1.5 2.5 3.5 4.5 5.5
>> attr(,"class")
>> [1] "integer" "foo"
>>
>> I do see the note in ?Arithmetic that states "All attributes
>(including
>> class) are preserved if there is no coercion".  Is this correct, or
>should
>> the returned value have an updated class of c("numeric", "foo")?
>Should foo
>> have its own methods to coerce the output to numeric?
>>
>> Thanks,
>> Cole
>>
>> ______________________________________________
>> 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.
>
>______________________________________________
>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.



More information about the R-help mailing list