代码之家  ›  专栏  ›  技术社区  ›  boshek

输出数据帧的循环中的错误处理

  •  1
  • boshek  · 技术社区  · 9 年前

    我试图在R中写一个循环,在那里我预期会出现一些错误。我没有停止循环,而是试图找出一种方法来捕获错误消息,并将该信息包含在输出中,然后继续循环。

    关于数据的说明: This 数据来自NOAA网站,是南方涛动指数数据。第二个集合很小(数据2),仅用于生成错误。

    这是我试图创建的循环类型的一个稍微简单的示例。从网络上获取一些数据,对其执行一些操作,将其存储(如 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
    }
    

    tryCatch_mod(read.csv("https://www.ncdc.noaa.gov/teleconnections/enso/indicators/soi/data2.csv",
                          skip = 2, col.names = c("Date","SOI")))
    

    我如何包括这个函数(或完成相同事情的东西),以便输出是有条件的,或者是否存在错误?也就是说,我如何编写函数,它本质上说:

    • 出现错误时,跳过任何操作并附加 i 并将错误消息输入
    1 回复  |  直到 9 年前
        1
  •  2
  •   Consistency    9 年前

    我重新创建您的数据。框架包括一个额外的列来存储错误消息,因为在R数据中。框架,一列应该存储一种类型的东西。在一列中存储错误消息和其他内容会很混乱,它们的类型将被强制为相同。这个 handle_i i 。错误处理是 tryCatch

    handle_i <- function(i){
        raw <- read.csv(
            paste0("https://www.ncdc.noaa.gov/teleconnections/enso/indicators/soi/",i,".csv"),
            skip = 2, col.names = c("Date","SOI") )
        list(mean_soi = mean(raw$SOI))
    }
    
    data_spec <- c("data", "data2")
    df <- data.frame(data_spec = data_spec, mean_soi = NA, message = "", stringsAsFactors = FALSE)
    for (i in 1:length(data_spec)) {
        r <- tryCatch(handle_i(data_spec[i]), error = function(e) list(message = e$message))
        df[i, names(r)] <- r
    }