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ę?
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"
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 lubtry()
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ć.
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"
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