我想使用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
是否有办法同时返回所需的消息,并从next
内发出tryCatch()
命令以执行此功能?
答案 0 :(得分:1)
使用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