R 中的 Switch 函数:当输入不匹配时如何抛出错误消息或默认值?

Switch function in R: how to throw an error message or default value when the input isn't matched?

在 R 中使用 switch(),如果 EXPR 的输入未在 switch 语句中定义,我该如何中止错误?

例如,考虑以下函数 animal_sound()。它接受动物名称和 return 动物发出的声音。

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"

但如果我们传递未定义的动物,return 值为空(甚至 NULL 也不行)。

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

有没有办法在输入不匹配的情况下抛出错误或设置默认 return 值?

本可以完成以下,这是一个不受欢迎的解决方案:

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.

reprex package (v0.3.0)

于 2021-10-18 创建

我不喜欢这个解决方案,因为它需要在开始时手动定义所有可能的输入。它既愚蠢(假设我们稍后在 switch() 中定义了相同的内容)又容易出错,以防我稍后向 switch 添加更多输入,并且可能忘记更新 valid_input 向量.

是否有 elegant/concise 方法来 return 在不支持输入的情况下显示信息性错误消息?

您可以使用 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")
}

您可以像这样添加一个默认值。

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

根据@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

reprex package (v0.3.0)

于 2021-10-18 创建