【发布时间】:2017-12-02 04:08:22
【问题描述】:
问题
我正在尝试在 R 中编写一个循环,我预计会出现一些错误。我没有停止循环,而是试图找出一种方法来捕获错误消息并将该信息包含在输出中并继续循环。
关于数据的注意事项:This 数据来自 NOAA 网站,它是南方涛动指数数据。第二组是微不足道的(data2),仅用于生成错误。
这是我尝试创建的循环类型的一个简单示例。从网络上获取一些数据,对其执行一些操作,将其存储(作为df)然后获取更多数据,执行相同的操作并将其(通过rbind)附加到第一个数据:
data_spec <- c("data")
df <- c()
for (i in data_spec){
raw <- read.csv(
paste0("https://www.ncdc.noaa.gov/teleconnections/enso/indicators/soi/",i,".csv"),
skip = 2, col.names = c("Date","SOI") )
u <- data.frame(data_spec = i, mean_soi = mean(raw$SOI))
df <- rbind(df, u)
}
因为https://www.ncdc.noaa.gov/teleconnections/enso/indicators/soi/data2.csv不是有效的url,所以循环停止并抛出错误:
文件中的错误(文件,“rt”):无法打开连接另外: 警告消息:在文件中(文件,“rt”):无法打开 URL 'https://www.ncdc.noaa.gov/teleconnections/enso/indicators/soi/data2.csv': HTTP 状态为“未找到 404”
预期输出
我正在尝试实现这样的输出,其中错误消息被捕获为对象并相应地附加:
data_spec mean_soi
1 data 0.1223618
2 data2 Error in file(file, rt) : cannot open the connection
试图解决这个问题
所以我想我很清楚我需要在这里使用tryCatch。如果我这样使用它:
data_spec <- c("data", "data2")
df <- c()
for (i in data_spec){
tryCatch({
raw <- read.csv(
paste0("https://www.ncdc.noaa.gov/teleconnections/enso/indicators/soi/",i,".csv"),
skip = 2, col.names = c("Date","SOI") )
u <- data.frame(data_spec = i, mean_soi = mean(raw$SOI))
df <- rbind(df, u)
}, error=function(e){cat("ERROR :",conditionMessage(e), "\n")})
}
循环继续进行,但输出中未捕获错误消息(不是我在这里期待的)。
另一种选择是使用从demo(error.catching) 输出的函数。我稍微修改了该函数,以便捕获错误消息:
tryCatch_mod <- function(expr)
{
W <- NULL
w.handler <- function(w){ # warning handler
W <<- w
invokeRestart("muffleWarning")
}
temp <- list(value = withCallingHandlers(tryCatch(expr, error = function(e) e),
warning = w.handler),
warning = W)
unlist(temp[[2]])$message
}
使用“data2”时会输出错误:
tryCatch_mod(read.csv("https://www.ncdc.noaa.gov/teleconnections/enso/indicators/soi/data2.csv",
skip = 2, col.names = c("Date","SOI")))
我想不通
如何包含此函数(或完成相同任务的函数)以便输出是有条件的或是否有错误?也就是说,我该如何编写它本质上说的函数:
- 出现错误时,跳过任何操作并将
i和错误消息附加到df - 当没有错误时,执行操作并将结果附加到相同的
df
【问题讨论】:
标签: r loops error-handling