【问题标题】:How do I write the argument verifications for functions in R. Can glue be used?如何为 R 中的函数编写参数验证。可以使用胶水吗?
【发布时间】:2019-11-18 19:08:45
【问题描述】:

我对在 r 中编写函数还很陌生。我想出了一个示例函数。我正在寻求以下方面的帮助:

  • 我有一个函数,其中包含可以作为特定选择之一的字符选择
  • 我想检查该选项是否是该选项字符向量的一部分(与标题大小写无关)
  • 如果可能的话,我还想使用glue::glue,这样我的错误消息就可以更加具体。下面的例子。

如果字符向量中只允许一个选项,或者允许多个选项,你能告诉我编写错误的代码的区别吗?

library(stringr)

sample_function <- function(choice = c("apples", "bananas", "cherries")) {

allowed_choices <- c("apples", "bananas", "cherries")


# match to lowercase 
choice <- str_to_lower(choice)

if(!choice %in% allowed_choices){
  stop("Please choose Apples, Bananas, or Cherries")
}

}

sample_function(choice = "Test")
#> Error in sample_function(choice = "Test"): Please choose Apples, Bananas, or Cherries
Created on 2019-11-18 by the reprex package (v0.3.0)

我可以在停止消息中执行以下操作吗?我希望字符向量用逗号分隔:

glue::glue("{choice} is not a valid choice.  Please choose from: {allowed_choices}")

【问题讨论】:

    标签: r function tidyverse


    【解决方案1】:

    有一个胶水函数glue_collapse 用于在最后一个元素之前用“或”(或其他东西)折叠这样的向量

    sample_function <- function(choice = c("apples", "bananas", "cherries")) {
    
      allowed_choices <- c("apples", "bananas", "cherries")
      allowed_choices_coll <- glue_collapse(allowed_choices, sep = ', ', last = ' or ')
    
      # match to lowercase 
      choice <- str_to_lower(choice)
      if(!choice %in% allowed_choices){
        stop(
          glue::glue("{choice} is not a valid choice.  Please choose from: {allowed_choices_coll}")
        )
      }
    
    }
    
    sample_function(choice = 'mango')
    
    # Error in sample_function(choice = "mango") : 
    #   mango is not a valid choice.  Please choose from: apples, bananas or cherries
    

    【讨论】:

    • 谢谢!所以我必须总是在函数中列出选择的字符向量?
    • 如果您想在错误消息中使用选择向量,您需要使该向量可用于函数。最佳实践是在函数内声明向量,使其自包含,但从技术上讲,如果您在全局环境中定义 allowed_choices,您的函数仍会找到它并能够用于错误消息。假设用户为choice 提供了他们自己的参数,我不知道有什么方法可以访问默认值。顺便说一句,使用默认值运行这个函数意味着你的if 条件是一个向量,会产生一个警告
    • 谢谢!您建议如何设置该功能?只列出一个选项,然后将其余选项放在文档中?
    • 我想这取决于函数应该如何工作。如果您希望它可能接受长度 >1 的向量,您可以将 if 更改为 if(!all(choice %in% allowed_choices))。否则,是的,我只会提供一个默认值或不提供默认值,并按照您的说法在文档中记录选择。
    【解决方案2】:

    我倾向于做以下事情:

    sample_function <- function(choice = c("apples", "bananas", "cherries")) {
      allowed_choices <- c("apples", "bananas", "cherries")
    
      extra_choices <- setdiff(choice, allowed_choices)
      if (length(extra_choices)) {
        stop("unrecognized 'choice': ", paste(sQuote(extra_choices), collapse = ","))
        # optional alternative
        stop("'choice' must be from ", paste(sQuote(allowed_choices), collapse = ","))
      }
    }
    

    假设您允许多个选择。

    您是否使用glue 取决于您,但paste(..., collapse) 可能有用。

    【讨论】:

      【解决方案3】:

      我们可以使用 str_c from stringr 折叠并在 glue 中使用它

      library(stringr)
      
      sample_function <- function(choice = c("apples", "bananas", "cherries")) {
      
      allowed_choices <- c("apples", "bananas", "cherries")
      
      
      # match to lowercase 
      choice <- str_to_lower(choice)
      
      concat_choices <- str_c(allowed_choices, collapse=", ")
      
      if(!choice %in% allowed_choices){
        stop(glue::glue("{choice} is not a valid choice.  Please choose from: {concat_choices}"))
      }
      
      }
      

      -测试

      sample_function(choice = "Test")
      

      sample_function(choice = "Test") 中的错误: test 不是一个有效的选择。请选择:苹果、香蕉、樱桃

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多