我想使用 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