获取错误消息中的变量?

时间:2014-05-28 14:04:29

标签: r error-handling

这是我的代码:

test <- function(y){
irisname <- c("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width","Species")
  if(y %in% irisname){
    print(y)
  } else{
    test <- function(...) stop("dummy error")
    test(y)
  }
}
> test("ds")
  Error in test(y) : dummy error 

在结果中:"Error in test(y) : dummy error ",我需要在测试中使用“ds”(“ds”),而不是测试(y)。

我该怎么做?

2 个答案:

答案 0 :(得分:5)

这几乎可以实现(有一个额外的冒号......),使用call.=FALSE来抑制有关调用的信息并将其入侵到错误消息中。

更新:为错误#1添加了引号;解释了为什么这个问题很难解决。

我不知道你的代码的结构,但你通过将对象更深入地传递到结构中来使自己的生活变得更加困难。从您的第一级直接致电stop()可以更轻松地直接在错误消息中使用y中提供的信息。

test <- function(y,stop=FALSE){
   irisname <- c("Sepal.Length","Sepal.Width",
       "Petal.Length","Petal.Width","Species")
   if (stop) stop(sprintf("premature stop: var %s",y))
   if(y %in% irisname){
       print(y)
   } else{
     test <- function(...) {
         stop(sprintf("in test(\"%s\"): dummy error",...),
               call.=FALSE)
     }
     test(y)
 }
}

test("junk")
## Error: in test("junk"): dummy error
test("junk",stop=TRUE)
## Error in test("junk", stop = TRUE) : premature stop: var junk

摆脱test("junk")输出中的虚假第一个冒号将相当更难,因为Error:字符串在R中是硬编码的。最好的选择是可能,不知何故,打印您自己的自定义错误消息,然后静默停止,或重新创建stop()的行为而不生成消息(请参阅?condition:例如return(invisible(simpleError("foo"))))。但是,你将不得不跳过很多箍来做这件事,并且很难确保你获得与stop()完全相同的行为(例如,错误消息会有已保存在错误消息缓冲区中?)

你想要做的事情可能是通过充分利用R内部构件来实现的,但在我看来,如此努力以至于重新思考这个问题会更好......

祝你好运。

答案 1 :(得分:3)

您可以在函数开头检查参数。 match.arg可能派上用场,或者您可以打印自定义消息并返回NA。

以下两个更新

> test <- function(y)
  {
    if(!(y %in% names(iris))){
      message(sprintf('test("%s") is an error. "%s" not found in string', y, y))
      return(NA) ## stop all executions and exit the function
    }
    return(y)  ## ... continue
  }

> test("Sepal.Length")
# [1] "Sepal.Length"
> test("ds")
# test("ds") is an error. "ds" not found in string
# [1] NA

添加/编辑:当函数转到else时,是否存在嵌套函数的原因?我删除了它,现在得到以下内容。看起来你正在做的就是检查一个参数,并且最终用户(和RAM)想要立即知道他们是否输入了错误的默认参数。否则,当您不需要时,您将调用不必要的作业并使用内存。

test <- function(y){
     irisname <- c("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width","Species")
     if(y %in% irisname){
         print(y)
     } else{
         stop("dummy error")
     }
 }
> test("ds")
# Error in test("ds") : dummy error
> test("Sepal.Length")
# [1] "Sepal.Length"

您也可以使用pmatch,而不是match.arg,因为match.arg会输出默认错误。

> test2 <- function(x)
  {
      y <- pmatch(x, names(iris))
      if(is.na(y)) stop('dummy error')
      names(iris)[y]
  }
> test2("ds")
# Error in test2("ds") : dummy error
> test2("Sepal.Length")
# [1] "Sepal.Length"