rclasstypeof

Why does the function toTitleCase not work with the english(1), but toupper does?


I'm using the library(english) to get my rmarkdown doc correct with APA guidelines on when to write out numbers as words. Super handy, I can just wrap my values in english() and they come out correct.

Obviously, when starting a sentence with a number it needs the first letter capitalized, so I'd thought I could just wrap english(1) in tools::toTitleCase(), but it doesn't like it:

Error in toTitleCase(english(1)) : 'text' must be a character vector

toupper(english(1)) works just as one might expect:

> toupper(english(1))
[1] "ONE"`

I have a working solution:

toTitleCase(as.character(english(1)))

Fine by me but...

...what's going on here? Why is toupper() able to deal with the output of english(1) as you'd expect, but toTitleCase() throws the error?

Reprex:

install.packages("english")
library(engilsh)
library(tools)

toTitleCase(english(1))

toupper(english(1))

EDIT:

I'm an idiot: there's the function english::Words(1), which does exactly what I wanted.


Solution

  • If you play around with the output of english(1), you will find that it has a class of "english" and having a type of "double", which is obviously not "character".

    library(english)
    
    class(english(1))
    [1] "english"
    
    typeof(english(1))
    [1] "double"
    

    And in the source code of toupper(), you can find that there is a statement to test whether your input is of type "character", if not, it will coerce it for you:

    toupper
    function (x) 
    {
        if (!is.character(x)) 
            x <- as.character(x)
        .Internal(toupper(x))
    }
    

    On the other hand, toTitleCase() will just throw an error if the input is not "character":

    toTitleCase ### only the relevant part is extracted below
    function (text) 
    {
      ###
      if (typeof(text) != "character") 
        stop("'text' must be a character vector")
    }
    

    Therefore, toupper can innately handle non-character input but toTitleCase cannot.