Usando switch() en R, ¿cómo puedo abortar con un error si la entrada a EXPR no está definida dentro de la instrucción switch ?
Por ejemplo, considere la siguiente función animal_sound() . Acepta el nombre de un animal y devuelve el sonido que hace el animal.
animal_sound <- function(x) { switch(x, "dog" = "woof", "cat" = "meow", "bee" = "bzzz", "duck" = "quack") } Siempre que el animal esté definido dentro de switch() , esto funciona.
animal_sound("bee") #> [1] "bzzz" animal_sound("cat") #> [1] "meow" Pero si pasamos un animal que no está definido, el valor de retorno está en blanco (ni siquiera NULL ).
animal_sound("alligator") ## nothing is printed to console¿Hay alguna forma de generar un error o establecer un valor de retorno predeterminado en caso de que la entrada no coincida?
Podría haber hecho lo siguiente, que es una solución no deseada:
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.Creado el 2021-10-18 por el paquete reprex (v0.3.0)
No me gusta esta solución porque requiere definir manualmente todas las entradas posibles al principio. Es tonto (dado que definimos lo mismo más adelante dentro switch() ) y propenso a errores en caso de que agregue más entradas para switch más adelante, y me olvide de actualizar el vector valid_input .
¿Existe una forma elegante/concisa de devolver un mensaje de error informativo en caso de que la entrada no sea compatible?
Puede comprobar los argumentos con la función match.arg() . Esto generará un mensaje de error apropiado.
No es menos propenso a errores, pero en este caso es una buena práctica ya que {Roxygen} puede presentar el argumento en uso.
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") }Puede agregar un valor predeterminado como este.
animal_sound <- function(x) { switch(x, "dog" = "woof", "cat" = "meow", "bee" = "bzzz", "duck" = "quack", "default") }Según la respuesta de @Norie y el comentario de @Roland, lo he adaptado un poco más.
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 supportedCreado el 2021-10-18 por el paquete reprex (v0.3.0)