Search code examples
rtypesfractionsr-s3

How do fractions vectors (from MASS) have error checking?


Take the following code that generates a fractions vector:

> example<-MASS:: as.fractions(c(0.2,0.4))
> example
[1] 1/5 2/5

If we were to replace one of these fractions with a string, we get the following error:

> example[1]<-"0/1"
Error in floor(x) : non-numeric argument to mathematical function

How does this happen? As far as I was concerned, fractions vectors aren't S4 objects and shouldn't have any sort of error checking, so how is floor(x) being ran when I'm trying to replace an entry in such a a vector?


Solution

  • fractions has an S3 [<- method:

    library(MASS)
    methods(class = "fractions")
    ## [1] [            [<-          as.character Math         Ops         
    ## [6] print        Summary      t           
    ## see '?methods' for accessing help and source code
    

    and have a look at the R source code at https://github.com/cran/MASS/blob/master/R/fractions.R

    floor is called in .rat which is called in fractions which is called in [<-.fractions which is invoked in the [<- generic.

    > example[1] <- "0/1"
    Error in floor(x) : non-numeric argument to mathematical function
    > traceback()
    5: matrix(floor(x))
    4: .rat(x, cycles, max.denominator)
    3: fractions(NextMethod())
    2: `[<-.fractions`(`*tmp*`, 1, value = "0/1")
    1: `[<-`(`*tmp*`, 1, value = "0/1")