2010-04-07 7 views
26

Mam poniżej przykładową funkcję, która odczytuje datę jako ciąg znaków i zwraca go jako obiekt daty. Jeśli odczytuje ciąg, którego nie może przekonwertować na datę, zwraca błąd.Jak powiedzieć lapply, aby zignorować błąd i przetworzyć kolejną rzecz na liście?

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ę na liście dat:

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

Ale jeśli chcesz zastosować funkcję na liście, gdy jeden ciąg w środku dwóch dobre daty 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) 

Przypuszczam, że chcę złapać try tam, ale czy jest jakiś sposób, aby złapać błąd dla „foo” string podczas gdy pytając lapply kontynuować i czytać trzeci dzień?

+1

bardzo ściśle powiązane: http://stackoverflow.com/questions/1395622/debugging-lapply-sapply-calls – Shane

Odpowiedz

44

Użyj tryCatch wyraz wokół funkcji, które mogą rzucić się komunikat o błędzie:

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

Zaletą funkcji tryCatch jest to, że można 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" 
+0

Na koniec dnia oboje robią to samo tutaj - a John nie potrzebuje obsługi wyjątków. Jeśli nie jest to data, zwracana jest NA. Po co utrudniać sprawę? –

+1

Tak, to prawda w tym przypadku.Chociaż jeśli pytanie jest uogólnione, użycie 'tryCatch' jest prawdopodobnie najlepszym sposobem na kontynuowanie błędu w' lapply'. Myślę, że przykład daty był tylko przykładem? – Shane

+0

Dzięki Dirkowi i Shane, w rzeczywistości szukanie wyjątków było tym, czego szukałem. Daty były tylko przykładem bardziej skomplikowanej funkcji, ale była to najłatwiejsza rzecz, jaką mogłem wymyślić, która zwróci błąd z listy rzeczy. – John

6

One mogą próbować keep it simple, zamiast zrobić to skomplikowane:

  • Użyj datę wektoryzowane analizowania
R> as.Date(c("2010-04-06", "foo", "2010-04-08")) 
[1] "2010-04-06" NA   "2010-04-08" 

Można trywialnie owinąć na.omit() lub cokolwiek wokół niego. Lub znajdź indeks NA i wyciągnij odpowiednio z początkowego wektora lub użyj uzupełnienia NA, aby znaleźć przeanalizowane daty, lub, lub, lub. Wszystko już jest tutaj.

  • Możesz zrobić swoje testFunction() coś zrobić. Użyj tam testu - jeśli zwrócona (przeanalizowana) data to NA, zrób coś.

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

Całe rzeczy jest trochę dziwne, jak przejść od struktury danych jednego typu (wektor od znaków) na coś innego, ale nie można łatwo mieszać typów chyba trzymać je w typie list. Więc może musisz to jeszcze raz przemyśleć.

0

Założenie, że testFunction() nie jest trywialne i/lub nie można go zmienić, może być zapakowane w funkcję własną przy pomocy bloku 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" 
Powiązane problemy