#r #switch-statement
Вопрос:
Используя switch()
в R, как я могу прервать с ошибкой, если вход в EXPR
не определен внутри switch
оператора?
Например, рассмотрим следующую функцию animal_sound()
. Он принимает имя животного и возвращает звук, который издает животное.
animal_sound <- function(x) {
switch(x,
"dog" = "woof",
"cat" = "meow",
"bee" = "bzzz",
"duck" = "quack")
}
Пока животное определено внутри switch()
, это работает.
animal_sound("bee")
#> [1] "bzzz"
animal_sound("cat")
#> [1] "meow"
Но если мы передадим животное, которое не определено, возвращаемое значение будет пустым (даже не NULL
).
animal_sound("alligator")
## nothing is printed to console
Есть ли способ либо выдать ошибку, либо установить возвращаемое значение по умолчанию в случае, если входные данные не совпадают?
Я мог бы сделать следующее, что является нежелательным решением:
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.
Создано в 2021-10-18 годах пакетом reprex (v0.3.0)
Мне не нравится это решение, потому что оно требует вручную определить все возможные входные данные в начале. Это и глупо (учитывая, что мы определяем то же самое позже внутри switch()
), и подвержено ошибкам в случае, если я добавлю больше входных данных switch
позже и могу забыть обновить valid_input
вектор.
Существует ли элегантный/лаконичный способ вернуть информативное сообщение об ошибке в случае, если ввод не поддерживается?
Комментарии:
1. Из онлайн-документа: «В случае отсутствия совпадения, если есть неназванный элемент … его значение возвращается.». Разве это не позволяет вам вернуть, скажем,
"Invalid"
или другой флаг?
Ответ №1:
Вы можете добавить значение по умолчанию, подобное этому.
animal_sound <- function(x) {
switch(x,
"dog" = "woof",
"cat" = "meow",
"bee" = "bzzz",
"duck" = "quack",
"default")
}
Комментарии:
1. Вы даже можете использовать
stop("some error message")
его по умолчанию.
Ответ №2:
Вы можете проверить аргументы с match.arg()
помощью функции. Это приведет к появлению соответствующего сообщения об ошибке.
Это не менее подвержено ошибкам, но в данном случае это хорошая практика, так как аргумент может быть представлен в использовании {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")
}
Ответ №3:
Основываясь на ответе @Norie и комментарии @Roland, я немного доработал его.
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
Создано в 2021-10-18 годах пакетом reprex (v0.3.0)