Использование tryCatch для пропуска выполнения при ошибке без выхода из lapply () - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь написать функцию, которая очищает электронные таблицы.Однако некоторые таблицы повреждены и не открываются.Я хочу, чтобы функция распознала это, напечатала сообщение об ошибке и пропустила выполнение остальной части функции (поскольку я использую lapply() для итерации по файлам) и продолжаю.Моя текущая попытка выглядит следующим образом:

candidate.cleaner <- function(filename){

  #this function cleans candidate data spreadsheets into an R dataframe

  #dependency check
  library(readxl)

  #read in

    cand_df <-  tryCatch(read_xls(filename, col_names = F),
    error = function (e){
            warning(paste(filename, "cannot be opened; corrupted or does not exist"))
    })
  print(filename)

  #rest of function

  cand_df[1,1]

}

test_vec <- c("test.xls", "test2.xls", "test3.xls")
lapply(FUN = candidate.cleaner, X = test_vec)

Тем не менее, он по-прежнему выполняет строку функции после оператора tryCatch, когда ему дан .xls файл, который не существует, который выбрасывает остановку, так как яЯ пытаюсь проиндексировать информационный фрейм, который не существует.Это выходит из вызова lapply.Как мне написать вызов tryCatch, чтобы пропустить выполнение остальной части функции без выхода из lapply?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Можно установить семафор в начале tryCatch(), указывающий, что все прошло хорошо, затем обработать ошибку и сообщить, что что-то пошло не так, и, наконец, проверить семафор и вернуться из функции с соответствующимзначение.

lapply(1:5, function(i) {
    value <- tryCatch({
        OK <- TRUE
        if (i == 2)
            stop("stopping...")
        i
    }, error = function(e) {
        warning("oops: ", conditionMessage(e))
        OK <<- FALSE                    # assign in parent environment
    }, finally = {
        ## return NA on error
        OK || return(NA)
    })
    ## proceed
    value * value
})

Это позволяет продолжать использовать инфраструктуру tryCatch(), например, для преобразования предупреждений в ошибки.Блок tryCatch() инкапсулирует весь соответствующий код.

0 голосов
/ 25 сентября 2018

Оказывается, это можно сделать простым способом с помощью try() и дополнительной справочной функции.

candidate.cleaner <- function(filename){

  #this function cleans candidate data spreadsheets into an R dataframe

  #dependency check
  library(readxl)

  #read in
  cand_df <- try(read_xls(filename, col_names = F))
  if(is.error(cand_df) == T){
  return(list("Corrupted: rescrape", filename))
  } else {
  #storing election name for later matching
  election_name <- cand_df[1,1]
}
}

Где is.error() взято из Advanced R Хэдли Уикхэма глава по отладке .Это определяется как:

is.error <- function(x) inherits(x, "try-error")
...