Home > OS >  Switch function in R: how to throw an error message or default value when the input isn't match
Switch function in R: how to throw an error message or default value when the input isn't match

Time:10-19

Using switch() in R, how can I abort with error if the input to EXPR is not defined inside the switch statement?

For example, consider the following function animal_sound(). It accepts an animal name and returns the sound the animal makes.

animal_sound <- function(x) {
  
  switch(x,
         "dog" = "woof",
         "cat" = "meow",
         "bee" = "bzzz",
         "duck" = "quack")
}

As long as the animal is defined within switch(), this works.

animal_sound("bee")
#> [1] "bzzz"
animal_sound("cat")
#> [1] "meow"

But if we pass an animal that isn't defined, the return value is blank (not even NULL).

animal_sound("alligator")
## nothing is printed to console

Is there a way to either throw an error or set a default return value in case the input has no match?

I could have done the following, which is an undesired solution:

animal_sound_with_error_message <- function(x) {
  
  valid_input_animals <- c("dog", "cat", "bee", "duck")
  input_is_valid <- any(x %in% valid_input_animals)
  
  if (!input_is_valid) {
    stop("animal is not supported. Try a different animal.")
  }
  
  switch(x,
         "dog" = "woof",
         "cat" = "meow",
         "bee" = "bzzz",
         "duck" = "quack")
  
}

animal_sound_with_error_message("bee")
#> [1] "bzzz"
animal_sound_with_error_message("cat")
#> [1] "meow"
animal_sound_with_error_message("alligator")
#> Error in animal_sound_with_error_message("alligator"): animal is not supported. Try a different animal.

Created on 2021-10-18 by the reprex package (v0.3.0)

I dislike this solution because it requires to manually define all possible input in the beginning. It is both silly (given that we define the same later inside switch()) and error-prone in case I add more inputs to switch later on, and may forget to update the valid_input vector.

Is there an elegant/concise way to return an informative error message in case the input isn't supported?

CodePudding user response:

You can check the arguments with the match.arg() function. This will generate an appropriate error message.

It not less error prone, but in this case it's a good practice since the argument can be presented in usage by {Roxygen}.

animal_sound_with_error_message <- function(x = c("dog", "cat", "bee", "duck")) {
  
  match.arg(x)
  
  switch(x,
         "dog" = "woof",
         "cat" = "meow",
         "bee" = "bzzz",
         "duck" = "quack")
}

CodePudding user response:

You can add a default like this.

animal_sound <- function(x) {
  
  switch(x,
         "dog" = "woof",
         "cat" = "meow",
         "bee" = "bzzz",
         "duck" = "quack",
         "default")
}

CodePudding user response:

Based on @Norie's answer and @Roland's comment, I've tailored it a bit further.

animal_sound <- function(x) {
  
  my_error <- rlang::abort(paste(x, "isnt supported", sep = " "))
  
  switch(x,
         "dog" = "woof",
         "cat" = "meow",
         "bee" = "bzzz",
         "duck" = "quack",
         my_error)
}


animal_sound("crocodile")
#> Error: crocodile isnt supported

Created on 2021-10-18 by the reprex package (v0.3.0)

  • Related