У меня есть функция в качестве примера ниже этого чтения на дате как строка, и возвращает его как объект даты. Если это читает строку, которую это не может преобразовать в дату, это возвращает ошибку.
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)
Я предполагаю, что хочу выгоду попытки там, но есть ли способ зафиксировать ошибку для строки "нечто" при просьбе lapply продолжать и читать третью дату?
Используйте выражение tryCatch
вокруг функции, которая может выдавать сообщение об ошибке:
testFunction <- function (date_in) {
return(tryCatch(as.Date(date_in), error=function(e) NULL))
}
Хорошая особенность функции tryCatch
заключается в том, что вы можете решить, что делать в случае ошибки (в этом случае вернуть NULL
).
> lapply(dates2, testFunction)
[[1]]
[1] "2010-04-06"
[[2]]
NULL
[[3]]
[1] "2010-04-08"
Можно попробовать не усложнять, а упростить:
R> as.Date( c("2010-04-06", "foo", "2010-04-08") ) [1] "2010-04-06" NA "2010-04-08"
Вы можете тривиально обернуть na.omit()
или что-то еще вокруг него. Или найти индекс NAs и извлечь их соответственно из исходного вектора, или использовать дополнение NAs для нахождения разобранных дат, или, или, или, или. Все это уже здесь.
Вы можете заставить свою testFunction()
делать что-то. Используйте тест там - если возвращаемая (разобранная) дата равна NA, сделайте что-нибудь.
Добавьте блок tryCatch()
или try()
к вашему разбору даты.
Все это немного странно, поскольку вы переходите от структуры данных одного типа (вектор символов) к чему-то другому, но вы не можете легко смешивать типы, если не храните их в типе list
. Так что, возможно, вам нужно переосмыслить это.
Предполагая, что 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"