如何围绕创建对象,保留对象和警告来编写tryCatch

时间:2017-05-23 13:55:41

标签: r

我正在运行很多模型,有些会抛出错误。我想保存所有输出和所有错误。但是,tryCatch来自here的我的attemts导致了一个代码,该代码返回警告,或者,如果没有警告,则返回并创建对象。这是代码:

DT <- iris
str(DT)
DT$binary <- as.numeric(DT$Petal.Width>1)
DT$dummy <- as.numeric(as.numeric(DT$Species)>2)

带有警告的模型会返回警告,但不会在环境中保留logit模型:

test <- tryCatch(
logit1 <- glm(binary~Sepal.Length+dummy,data = DT, family = binomial( link = 'logit')),
warning = function( w ) { conditionMessage( w ) } )

没有警告的模型会在环境中创建logit对象,但是当我将此tryCatch保存为对象时,它就是整个logit输出。

test <- tryCatch(
logit2 <- glm(binary~Sepal.Length+Sepal.Width,data = DT, family = binomial( link = 'logit')),
warning = function( w ) { conditionMessage( w ) } )

好像tryCatch甚至不存在(我认为因为条件不满足而有意义)。我正在寻找代码,它没有给我任何东西,0或NA,如果没有警告,但警告消息,如果有警告,并创建命名logit模型,无论是否有警告。不知怎的,tryCatch似乎不太适合这个,理想情况下,我只是运行logit并保存警告信息,如果可能的话?

1 个答案:

答案 0 :(得分:1)

以下是一些显示如何

的代码
  • 拦截函数引发的警告和错误,以便您可以在此时执行任何操作(例如存储消息),并且
  • 返回函数的结果,如果它没有引发错误,并返回其他内容,如果它确实引发了错误。

这不是您想要的,但您应该能够对其进行调整以解决您的问题。

首先,这是一个有时会引发警告和错误的函数:

f <- function(x) {
    if (x %% 2 == 0) warning("warning number 1")
    if (x %% 3 == 0) warning("warning number 2")
    if (x %% 5 == 0) stop("error number 1")
    if (x %% 7 == 0) stop("error number 2")
    return(100)
}

这是一个包裹f的函数,并拦截它引发的任何警告和错误:

g <- function(x) {
    errorMessage <- character()
    warningMessages <- character()

    result <- withCallingHandlers(
            tryCatch(
                    f(x),
                    error = function(e) {
                        # Code here will be run if f raises an error. 
                        errorMessage <<- conditionMessage(e)
                        # To edit the error message and raise the error, use this:
                        # stop("some extra text\n", conditionMessage(e))
                        return(200)  # this will be assigned to result
                    }
            ), 
            warning = function(w) {
                # Code here will be run if f raises a warning. 
                warningMessages <<- append(warningMessages, conditionMessage(w))
                # To edit the warning message and raise the warning, use this:
                # warning("some extra text\n", conditionMessage(w))
                # The following line is needed at the end to transfer control
                # back to the appropriate place in f:
                invokeRestart("muffleWarning")
            }
    )

    if (length(warningMessages) > 0)
        cat("WARNINGS:\n", paste(warningMessages, collapse="\n"), "\n", sep="")
    if (length(errorMessage) > 0)
        cat("ERROR:\n", paste(errorMessage, collapse="\n"), "\n", sep="")
    return(result)
}

以下是没有警告或错误时会发生的情况:

> g(11)
[1] 100

当有警告但没有错误时:

> g(6)
WARNINGS:
warning number 1
warning number 2
[1] 100

出现错误时:

> g(35)
ERROR:
error number 1
[1] 200

当有警告和错误时:

> g(42)
WARNINGS:
warning number 1
warning number 2
ERROR:
error number 2
[1] 200

所以你有。如您所见,g中的代码并不容易理解。像invokeRestart("muffleWarnings")这样的东西没有很好地记录下来。