Как сказать, чтобы проигнорировать ошибку и обработать следующую вещь в списке?
У меня есть примерная функция ниже, которая читает в дате как строку и возвращает ее как объект даты. Если он читает строку, которую он не может преобразовать в дату, он возвращает ошибку.
testFunction <- function (date_in) {
return(as.Date(date_in))
}
testFunction("2010-04-06") # this works fine
testFunction("foo") # this returns an error
Теперь я хочу использовать lapply и применить эту функцию к списку дат:
dates1 = c("2010-04-06", "2010-04-07", "2010-04-08")
lapply(dates1, testFunction) # this works fine
Но если я хочу применить функцию над списком, когда одна строка в середине двух хороших дат вернет ошибку, каков наилучший способ справиться с этим?
dates2 = c("2010-04-06", "foo", "2010-04-08")
lapply(dates2, testFunction)
Я предполагаю, что хочу попробовать ухватить там, но есть ли способ поймать ошибку для строки "foo", прося продолжить и прочитать третью дату?
Ответы
Ответ 1
Используйте выражение tryCatch
вокруг функции, которая может вывести сообщение об ошибке:
testFunction <- function (date_in) {
return(tryCatch(as.Date(date_in), error=function(e) NULL))
}
Хорошая вещь о функции tryCatch
заключается в том, что вы можете решить, что делать в случае ошибки (в этом случае return NULL
).
> lapply(dates2, testFunction)
[[1]]
[1] "2010-04-06"
[[2]]
NULL
[[3]]
[1] "2010-04-08"
Ответ 2
Можно попытаться сохранить его просто, а не усложнять:
- Используйте синтаксический анализ с векторизованной датой
R> as.Date( c("2010-04-06", "foo", "2010-04-08") )
[1] "2010-04-06" NA "2010-04-08"
Вы можете тривиально обернуть na.omit()
или что угодно вокруг него. Или найдите индекс NA и выберете соответственно из исходного вектора или воспользуйтесь дополнением к NA, чтобы найти разобранные даты, или, или, или. Это все уже здесь.
-
Вы можете сделать свой testFunction()
что-то. Используйте тест там - если возвращенная (разобранная) дата - NA, сделайте что-нибудь.
-
Добавьте блок tryCatch()
или try()
в синтаксический анализ даты.
Все вещи немного странны, поскольку вы переходите от структуры данных одного типа (вектор символов) к чему-то еще, но вы не можете легко смешивать типы, если не сохранить их в типе list
. Поэтому, возможно, вам нужно переосмыслить это.
Ответ 3
Предполагая, что testFunction()
не является тривиальным и/или что его нельзя изменить, его можно обернуть в свою собственную функцию с помощью блока tryCatch(). Например:
> FaultTolerantTestFunction <- function(date_in) {
+ tryCatch({ret <- testFunction(date_in);}, error = function(e) {ret <<- NA});
+ ret
+ }
> FaultTolerantTestFunction('bozo')
[1] NA
> FaultTolerantTestFunction('2010-03-21')
[1] "2010-03-21"