r语言 - 返回'next'并从 tryCatch 函数打印消息以跳到下一个循环迭代



我想使用 tryCatch() 来检查包是否从循环中安装,然后返回 next 进行突破,如果包加载或安装失败,则跳到循环的下一次迭代。同时,我想向控制台返回一条消息,报告此问题。我可以做一个,或者另一个,但我很难弄清楚如何同时做这两个。例如,这项工作:

package_list<-c("ggplot2", "grid", "plyr")
for(p in package_list){
  # check if package can't be loaded
  if(!require(p,character.only=TRUE,quietly=TRUE,warn.conflicts=FALSE)){
    write(paste0("Attempting to install package: ",p), stderr())
    # try to install & load the packages, give a message upon failure
    tryCatch(install.packages(p,repos="http://cran.rstudio.com/"),
             warning = function(e){write(paste0("Failed to install pacakge: ", p), stderr())},
             error = function(e){write(paste0("Failed to install pacakge: ", p), stderr())})
    tryCatch(library(p,character.only=TRUE,verbose=FALSE),
             warning = function(e){write(paste0("Failed to install pacakge: ", p), stderr())},
             error = function(e){write(paste0("Failed to install pacakge: ", p), stderr())})
    # try to install & load the packages, skip to next loop iteration upon failure
    tryCatch(install.packages(p,repos="http://cran.rstudio.com/"),warning = next)
    tryCatch(library(p,character.only=TRUE,verbose=FALSE),warning = next)
  }
}

但这需要运行每个命令两次;一次失败并返回有关失败的消息,然后再次失败并跳到循环中的下一项。

相反,我宁愿使用单个函数执行这两个操作,如下所示:

for(p in package_list){
  if(!require(p,character.only=TRUE,quietly=TRUE,warn.conflicts=FALSE)){
    tryCatch(install.packages(p,repos="http://cran.rstudio.com/"),
             warning = function(e){print(paste("Install failed for package: ", p)); return(next)})
    # ...
  }
} 

但是,此操作会失败,因为您无法在函数中使用next

Error in value[[3L]](cond) : no loop for break/next, jumping to top level

有没有办法既返回所需的消息,又从tryCatch()内部发出next命令以执行此功能?

使用message()而不是write(..., stderr());它需要几个不必一起paste()的参数。

使用 tryCatch() 返回状态代码,并对状态代码执行操作;下面

for (i in 1:10) {
    status <- tryCatch({
        if (i < 5) warning("i < 5")
        if (i > 8) stop("i > 8")
        0L
    }, error=function(e) {
        message(i, ": ", conditionMessage(e))
        1L
    }, warning=function(w) {
        message(i, ": ", conditionMessage(w))
        2L
    })
    if (status != 0L)
        next
    message("success")
}

指纹

1: i < 5
2: i < 5
3: i < 5
4: i < 5
success
success
success
success
9: i > 8
10: i > 8

最新更新