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

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

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 продолжать и читать третью дату?

35
задан zx8754 2 November 2016 в 19:26
поделиться

3 ответа

Используйте выражение 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"
59
ответ дан 27 November 2019 в 07:02
поделиться

Можно попробовать не усложнять, а упростить:

  • Используйте векторный разбор даты
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. Так что, возможно, вам нужно переосмыслить это.

7
ответ дан 27 November 2019 в 07:02
поделиться

Предполагая, что 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"
0
ответ дан 27 November 2019 в 07:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: