【问题标题】:How to trap wrong or undefined arguments in R function calls when ellipsis is used in definition在定义中使用省略号时如何在 R 函数调用中捕获错误或未定义的参数
【发布时间】:2016-02-15 01:54:18
【问题描述】:

我正在努力解决一个公认但我尚未找到简单解决方案的问题:当函数定义包含省略号或三个点 ... 时,如何捕获传递给 R 函数的错误指定参数。

如 Wickham 的Advanced R所述:

使用... 是有代价的——任何拼写错误的论点都不会引发 一个错误,... 之后的任何参数都必须完全命名。这使得 错别字很容易被忽视。

这是一个例子:

myfun <- function(x, ...) 
    UseMethod("myfun")

myfun.character <- function(x, toLower = FALSE, ...)
    cat("Sent and transformed by myfun:", ifelse(toLower, tolower(x), x), "\n")

myfun("Test String with CaPiTaLs.")
## Sent and transformed by myfun: Test String with CaPiTaLs.
myfun("Test String with CaPiTaLs.", toLower = TRUE)
## Sent and transformed by myfun: test string with capitals. 
myfun("Test String with CaPiTaLs.", tolower = TRUE)
## Sent and transformed by myfun: Test String with CaPiTaLs.
myfun("Test String with CaPiTaLs.", toLower = TRUE, notDefined = 1)
## Sent and transformed by myfun: test string with capitals. 

这里,toLower 的细微拼写错误不会导致任何可见的错误,除了输出失败为小写,正如用户可能预期的那样。在最后一个示例中,用户认为是函数式的参数不是,但由于... 的性质,它们只是消失在以太中。

当然我可以检查...list(...) 的内容,但我想知道是否有更好的方法,链接到函数中定义的形式或传递... 的形式。

顺便说一句,有人知道我们应该如何称呼... 吗?我几乎可以肯定我在 Julia 文档中看到了一个带有名称的参考,但现在找不到这个!

添加:

理想情况下,如果参数不是应该在省略号中传递的内容,而在被调用函数范围内的某些内容通过省略号传递给子公司时,理想情况下,我想找出生成错误的最佳方法争论。例如,如何最好地捕获这些错误:

myfun2 <- function(x, ...) 
    UseMethod("my fun")

myfun2.character <- function(x, toLower = FALSE, ...)
    cat("Sent and transformed by myfun:", ifelse(toLower, tolower(x), x), "\n", ...)

myfun2("Test String with CaPiTaLs.", tolower = TRUE)
## Sent and transformed by myfun: Test String with CaPiTaLs. 
##  TRUE
myfun2("Test String with CaPiTaLs.", toLower = TRUE, notDefined = 1)
## Sent and transformed by myfun: test string with capitals. 
##  1
myfun2("Test String with CaPiTaLs.", sep = "\tXX\t")
## Sent and transformed by myfun:   XX  Test String with CaPiTaLs.  XX  

【问题讨论】:

  • 您想在您的myfun.character 中使用... 吗?如果没有,检查可能只是if (length(list(...))) stop(...)
  • 称为省略号。我在此示例中看到了两个选项:不为 toLower 提供默认值或包含替代拼写作为参数,例如 toLower = tolower
  • 这是一个非常简化的示例,但我正在考虑如何在具有更长函数签名和许多命名形式的包中管理它。我担心如果我尝试对 list(...) 内容进行手动检查,那么当我的检查与函数签名不同时,我会增加出错的可能性。
  • 我认为也许 S4 可能会有所帮助,但事实并非如此。
  • 您能说明一下您想要实现的目标吗? myfun("Test String with CaPiTaLs.", tolower = TRUE) 应该返回什么,为什么要返回?现在,您的问题看起来就像您同时想要使用 ... 而不是使用它。

标签: r function error-handling


【解决方案1】:

我不会返回错误。一个警告就足够了。像这样的:

myfun2.character <- function(x, toLower = FALSE, ...) {
  elli <- names(list(...))
  check <- elli %in% names(formals(cat))
  if (any(!check)) warning(sprintf("%s is not an expected parameter. Did you misstype it?", 
                                   paste(elli[!check], collapse = ", ")))
  cat("Sent and transformed by myfun:", ifelse(toLower, tolower(x), x), "\n", ...)
}


myfun2("Test String with CaPiTaLs.", tolower = TRUE)
#Sent and transformed by myfun: Test String with CaPiTaLs. 
#TRUE
#Warning message:
#  In myfun2.character("Test String with CaPiTaLs.", tolower = TRUE) :
#  tolower is not an expected parameter. Did you misstype it?
myfun2("Test String with CaPiTaLs.", toLower = TRUE, notDefined = 1)
#Sent and transformed by myfun: test string with capitals. 
#1
#Warning message:
#  In myfun2.character("Test String with CaPiTaLs.", toLower = TRUE,  :
#                        notDefined is not an expected parameter. Did you misstype it?
myfun2("Test String with CaPiTaLs.", sep = "\tXX\t")
## Sent and transformed by myfun:   XX  Test String with CaPiTaLs.  XX

我不认为最后一个应该警告。无论如何你都应该避免位置参数匹配,如果你在那里使用名称匹配,你会得到一个错误,你需要捕获它。

【讨论】:

猜你喜欢
  • 2017-01-17
  • 2017-08-04
  • 1970-01-01
  • 2018-01-31
  • 2016-06-11
  • 2017-07-25
  • 2019-04-02
  • 2016-04-09
  • 2020-04-29
相关资源
最近更新 更多