如果在 R 中失败,则移至下一个代码行

Posted

技术标签:

【中文标题】如果在 R 中失败,则移至下一个代码行【英文标题】:Move to the next code line if failed In R 【发布时间】:2019-12-16 09:21:58 【问题描述】:

我不知道如何在 Google 上搜索它。 我有一个相互独立的行代码 - 假设一行由于某种原因失败,那么脚本的其余部分不会继续。如何让它继续?

例如:

library(RODBC)
library(sqldf)
myconn<-odbcConnect("production")

#第 1 行: sqlQuery(myConn,"exec sp_v_table_1")

#第 2 行: sqlQuery(myConn,"exec sp_v_table_2")

也因为第 1 行失败而失败

另外,我怎么知道某个代码行——例如:

sqlQuery(myConn,"exec sp_v_table_3") 

成功通过了,没有失败?

【问题讨论】:

【参考方案1】:

你可以使用 tryCatch 块,你有一个参考 here

这里有一个使用它来处理请求的示例:

urls <- c(
"http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html",
"http://en.wikipedia.org/wiki/Xz",


   "xxxxx"
)

readUrl <- function(url) 
    out <- tryCatch(
        
            # Just to highlight: if you want to use more than one 
            # R expression in the "try" part then you'll have to 
            # use curly brackets.
            # 'tryCatch()' will return the last evaluated expression 
            # in case the "try" part was completed successfully
        message("This is the 'try' part")

        readLines(con=url, warn=FALSE) 
        # The return value of `readLines()` is the actual value 
        # that will be returned in case there is no condition 
        # (e.g. warning or error). 
        # You don't need to state the return value via `return()` as code 
        # in the "try" part is not wrapped insided a function (unlike that
        # for the condition handlers for warnings and error below)
    ,
    error=function(cond) 
        message(paste("URL does not seem to exist:", url))
        message("Here's the original error message:")
        message(cond)
        # Choose a return value in case of error
        return(NA)
    ,
    warning=function(cond) 
        message(paste("URL caused a warning:", url))
        message("Here's the original warning message:")
        message(cond)
        # Choose a return value in case of warning
        return(NULL)
    ,
    finally=
    # NOTE:
    # Here goes everything that should be executed at the end,
    # regardless of success or error.
    # If you want more than one expression to be executed, then you 
    # need to wrap them in curly brackets (...); otherwise you could
    # just have written 'finally=<expression>' 
        message(paste("Processed URL:", url))
        message("Some other message at the end")
    
)    
return(out)

来源来自this*** 的回复,我明显推荐你看看。

【讨论】:

【参考方案2】:

使用try 命令。

通常这会导致错误并阻止之后的代码运行:

x <- "a" + 1
y <- 1
y

但是,如果我们将赋值运算符后面的部分包装在 try 中,则会打印错误但之后编写的代码仍然可以运行:

x <- try("a" + 1)
y <- 1
y

请注意,x 具有类 "try-error"

class(x)
"try-error"

因此,在您的示例中,您可以执行以下操作以确保后面的行运行,同时仍然能够拾取前面失败的行:

x <- try(sqlQuery(myConn,"exec sp_v_table_3"))
y <- 1
y
class(x) 

对象y 仍然会被创建,x 的类会告诉你sqlQuery(myConn,"exec sp_v_table_3") 是否运行成功。

tryCatch 在某种意义上是try 的更灵活版本。 try 只会在发生错误时返回类 "try-error" 并允许后面的代码行运行,但 tryCatch 将允许您指定发生错误时想要发生的情况。如果出现warning 或者即使代码成功运行,您也可以指定要发生的情况。

purrr::safelytryCatch 的包装。那里针对错误指定的操作是返回一个包含两个元素的列表:备用输出(默认为NULL)和错误消息。

【讨论】:

【参考方案3】:

您需要一种方法来捕获错误。 为此目的,我欣赏的一个工具是来自purrrpackage 的safely()

您在现有函数调用周围包装一个函数,即使发生错误,也可以安全地返回输出。

来自文档(log() 示例):

safe_log <- safely(log)
safe_log(10)
#> $result
#> [1] 2.302585
#> 
#> $error
#> NULL
#> 
safe_log("a")
#> $result
#> NULL
#> 
#> $error
#> <simpleError in .Primitive("log")(x, base): non-numeric argument to mathematical function>
#> 

这将返回一个列表,其中包含一个结果和一个错误元素。

【讨论】:

以上是关于如果在 R 中失败,则移至下一个代码行的主要内容,如果未能解决你的问题,请参考以下文章

IntelliJ:移至下一个错字

移至下一个空行以从Userform填充单元格

如何使用 jQuery 将焦点移至下一个输入?

避免在较小的屏幕上将第二行移至下一行 Bootstrap 3

Python:如何使 Reportlab 在 PDF 输出中移至下一页

BasicSort — InsertionSort