match.arg behaviour not coherent

Viewed 42

I find this behavior very confusing:

choose_language <- function(language = c("R", "python", "C")) {   
   language <- match.arg(language, several.ok = FALSE)   
   paste('I love', language)  
}

choose_language(language = "R")

"I love R"

choose_language(language = c("R", "python"))

Error in ... OK

choose_language(language = c("R", "python", "C"))

"I love R"

Why this happen?

I would expect the same behavior as the following function:

choose_language <- function(language = "R") {
checkmate::assertChoice(language, choices = c("R", "python", "C"))
  paste('I love', language)  
}

but without checkmate dependency

Thanks again

1 Answers

Your usage of match.arg() within the choose_language() function is correct, but it is the one-argument form of match.arg(). Check the documentation specifically for this:

"In the one-argument form match.arg(arg), the choices are obtained from a default setting for the formal argument arg of the function from which match.arg was called. (Since default argument matching will set arg to choices, this is allowed as an exception to the ‘length one unless several.ok is TRUE’ rule, and returns the first element.)"

If you update your function to explicitly include the choices argument, like this

choose_language <- function(language = c("R", "python", "C")) {   
  language <- match.arg(arg=language, choices = language, several.ok = FALSE)   
  paste('I love', language)  
}

then you will find that all of your above examples return "I love R" `

Related