Jak powiedzieć lapply, aby zignorował błąd i przetworzył następną rzecz na liście?

Poniżej znajduje się przykładowa funkcja, która odczytuje datę jako łańcuch znaków i zwraca ją jako obiekt date. Jeśli odczytuje ciąg znaków, którego nie można przekonwertować na datę, zwraca błąd.

testFunction <- function (date_in) {
    return(as.Date(date_in))
    }

testFunction("2010-04-06")  # this works fine
testFunction("foo")  # this returns an error

Teraz chcę użyć lapply i zastosować tę funkcję nad listą dat:

dates1 = c("2010-04-06", "2010-04-07", "2010-04-08")
lapply(dates1, testFunction)  # this works fine

Ale jeśli chcę zastosować funkcję na liście, gdy jeden ciąg znaków w środku dwóch dobrych dat zwraca błąd, jaki jest najlepszy sposób, aby sobie z tym poradzić?

dates2 = c("2010-04-06", "foo", "2010-04-08")
lapply(dates2, testFunction)

Zakładam, że chcę spróbować Złap tam, ale czy istnieje sposób, aby złapać błąd Dla ciągu " foo " podczas prosząc lapply, aby kontynuować i przeczytać trzecią datę?

Author: zx8754, 2010-04-07

3 answers

Użyj wyrażenia tryCatch wokół funkcji, która może wyświetlać komunikat o błędzie:

testFunction <- function (date_in) {
  return(tryCatch(as.Date(date_in), error=function(e) NULL))
}

Fajną rzeczą w funkcji tryCatch jest to, że możesz zdecydować, co zrobić w przypadku błędu(w tym przypadku, return NULL).

> lapply(dates2, testFunction)
[[1]]
[1] "2010-04-06"

[[2]]
NULL

[[3]]
[1] "2010-04-08"
 49
Author: Shane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-07 01:01:01

Można by próbować to uprościć, a nie skomplikować:

  • użyj wektoryzowanego parsowania daty
R> as.Date( c("2010-04-06", "foo", "2010-04-08") )
[1] "2010-04-06" NA           "2010-04-08"

Możesz trywialnie owinąć na.omit() lub cokolwiek wokół niego. Lub znajdź indeks NAs i wyodrębnij odpowiednio z wektora początkowego, lub użyj dopełniacza NAs, aby znaleźć przetwarzane daty, or, or, or. Wszystko już tu jest.

  • Możesz sprawić, że Twój testFunction() coś zrobi. Użyj tam testu -- jeśli zwrócona (przetworzona) Data na, zrób coś.

  • Dodaj tryCatch() blok lub try() do analizy daty.

Całość jest trochę dziwna, ponieważ przechodzisz od struktury danych jednego typu (wektor znaków) do czegoś innego, ale nie możesz łatwo mieszać typów, chyba że utrzymasz je w typie list. Więc może musisz to przemyśleć.

 7
Author: Dirk Eddelbuettel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-07 01:01:13

Zakładając, że testFunction() nie jest trywialna i / lub że nie można jej zmienić, można ją zawinąć w własną funkcję z blokiem tryCatch (). Na przykład:

> 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
Author: mjv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-07 02:41:03