在R中创建并处理异常

时间:2013-03-26 18:53:09

标签: r exception exception-handling

我希望有一个函数,对于它抛出的特定异常并返回一条消息,然后只需检查返回的内容是否是我定义的“异常”之一。比如说我有这个功能:

divideByX <- function(x){
    # If x is NA throws exception
    if(is.na(x)){
        return(exception('x is NA'))
    }
    # If x is 0 throws exception
    else if(x == 0){
        return(exception('Cannot divide by zero'))
    }
    else{
        return(10/x)
    }
}

因此,如果x为0,则返回指示“不能除以零”,如果x为NA,则返回异常“x is NA”,对于x的所有其他值,则尝试计算表达式10 / x。 / p>

然后我想要运行这样的东西:

tempList <- list('a' = 2, 'b' = 0, 'c' = 5, 'd' = NA)
lapply(tempList, function(x){
   if(is.exception(x)){
       return(x)
   }
   else{
       y <- divideByX(x)
       return(y^2)
   }
 })

因此它首先检查该值是否是我定义的异常之一,如果是,则返回消息,否则它将我的值平方,所以上面应该返回

$a
[1] 25

$b
[1] 'Cannot divide by zero'

$c
[1] 4

$d
[1] 'x is NA'

有谁知道最好的方法吗?如果有任何不清楚的地方,请告诉我。

提前致谢

2 个答案:

答案 0 :(得分:2)

创建一个生成异常的函数。例外可以是扩展简单错误类

的线性层次结构
exception <-
    function(class, msg)
{
    cond <- simpleError(msg)
    class(cond) <- c(class, "MyException", class(cond))
    stop(cond)
}

这是你的功能

divideByX <- function(x){
    # If x is 0 throws exception
    if (length(x) != 1) {
        exception("NonScalar", "x is not length 1")
    } else if (is.na(x)) {
        exception("IsNA", "x is NA")
    } else if (x == 0) {
        exception("DivByZero", "divide by zero")
    }
    10 / x
}

并用于生成您要求的输出

lapply(tempList, function(x) tryCatch({
    divideByX(x)
}, MyException=function(err) {
    conditionMessage(err)
}))

或以不同于其他人的方式处理某些例外

> lapply(list(NA, 3:5), function(x) tryCatch({
+     divideByX(x)
+ }, IsNA=function(err) {
+     warning(err)  # signal a warning, return NA
+     NA
+ }, NonScalar=function(err) {
+     stop(err)     # fail
+ }))
Error: x is not length 1
In addition: Warning message:
x is NA 

答案 1 :(得分:0)

除非你总是除以10,否则你需要在yoru函数中包含分子。

    divideByX <- function(X, num=10) { 

    if(is.na(X)) 
        return('X is NA')
    if(X == 0) 
        return('Cannot divide by zero')

    return(num / X)
    }

用法:

y <- 3
lapply(tempList, divideByX, num=y^2)
#   $a
#   [1] 4.5
#   
#   $b
#   [1] "Cannot divide by zero"
#   
#   $c
#   [1] 1.8
#   
#   $d 
#   [1] "X is NA"