Как сказать Lapply игнорировать ошибку и обработать следующую вещь в списке?

StackOverflow https://stackoverflow.com/questions/2589275

Вопрос

У меня есть пример функции ниже, который читается в дате строки, и возвращает ее в качестве объекта даты. Если он считывает строку, которую она не может преобразовать на дату, она возвращает ошибку.

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», в то время как просит ловушку продолжить и прочитать третий дату?

Это было полезно?

Решение

Использовать 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"

Другие советы

Можно попытаться сохранить его просто, а не сделать его сложным:

  • Используйте фактическое распределение даты
R> as.Date( c("2010-04-06", "foo", "2010-04-08") )
[1] "2010-04-06" NA           "2010-04-08"

Вы можете тривиально обернуть na.omit() или что угодно вокруг этого. Или найти индекс NAS и извлекать соответственно от начального вектора или используйте дополнение NAS, чтобы найти даты анализируемых, или, или, или. Это уже все здесь.

  • Вы можете сделать ваш testFunction() сделай что-нибудь. Используйте тест там - если возвращенная (проанализированная) дата дана, сделайте что-нибудь.

  • Добавить 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"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top