Odpowiednik „rzutu” w R.


140

Jak można „zgłosić” błąd w R? Mam funkcję, która pobiera ramkę danych i niektóre nazwy kolumn i robi z nimi rzeczy. Jeśli kolumny nie istnieją, chcę, aby funkcja zatrzymała się i zatrzymała wszystkie zależne od niej funkcje.

Mam spojrzał na recoveri browsea traceback, ale dobrze, że wydawała się być blisko, ale nie to, czego szukam.


2
Dobrze, odzyskiwanie, przeglądarka i śledzenie służą do debugowania, a systemy try / catch służą do obsługi błędów w kodzie produkcyjnym.
Harlan

20
Uwielbiam, gdy pytający używają nazwy funkcji, której szukają wielokrotnie w pytaniu;)
hadley,

Myślę, że jest powód, dla którego to pytanie ma więcej głosów pozytywnych niż najlepsza odpowiedź. Mimo że to drugie pytanie jest technicznie niezwiązane z tematem, jest to bardzo zwięzłe podsumowanie nieznanego tematu, z którego słynie Stack Overflow.
Josiah Yoder

Odpowiedzi:


113

Zobacz help(tryCatch):

Warunki są sygnalizowane przez „ signalCondition”. Ponadto funkcje
stop” i „ warning” zostały zmodyfikowane tak, aby akceptowały również
argumenty warunku.

a później w sekcji „Zobacz też”:

stop” i „ warning” warunki sygnału, a „ try” jest zasadniczo uproszczoną wersją „ tryCatch”.

więc prawdopodobnie chcesz stop.


24
To działa doskonale. R jest tak dziwny, nie z ich winy - został zaprojektowany na długo przed tym, zanim opracowaliśmy dobrze zinterpretowany projekt języka.
forkandwait

5
Zdaniem autorów duży wpływ na to miał Schemat, który jest zarówno stary, jak i dobry. R jest „lispy”, ale z funky strukturami danych. „Ciekawe” części języka R są prawdopodobnie związane z tym, że wiele konwencji różni się od innych języków, zwłaszcza rodzina języków C, która jest również bliska składniowo. Myślę, że język został opracowany przez grupę statystyków, którzy potrzebowali dobrego narzędzia, a nie programiści potrzebujący dobrego narzędzia.
Sam

5
Kilka podstawowych przykładów byłoby świetne, nie tylko z cytatami. Tutaj stackoverflow.com/a/23917007/54964
Léo Léopold Hertz 준영

Doszedłem do tego pytania, szukając, jak ponownie zgłosić błąd w R z rozsądniejszym komunikatem o błędzie, ale zachowując nienaruszony ślad (tak jak w, wykonujesz traceback()po błędzie, aby zobaczyć, co poszło nie tak). Korzystanie stopz errorargumentem tryCatchbędzie bałagan śladu. Jednak finallyargument pozwoli na rzucenie dodatkowej wiadomości i sprawi, że śledzenie będzie przydatne. Niezupełnie na temat, ale czuję, że jest na tyle ważny, że uzasadnia kilka minusów i groźbę umiarkowania, która wyrzuci ten komentarz z okna. :-)
Mali Remorker


8

Poza podstawowymi funkcjami, o których wspomina Dirk:

Pakiet R.oo dodatkowe funkcje obsługi wyjątków, w tym funkcji rzut (), która jest bardzo przydatna. Możesz łapać wyjątki za pomocą zwykłych funkcji try lub trycatch:

> try(throw("Division by zero.")); print("It's ok!");
Error: [2009-10-22 10:24:07] Exception: Division by zero.
[1] "It's ok!"

Możesz przeczytać więcej na ten temat tutaj: http://www1.maths.lth.se/help/R/R.oo/


8
Hehe. R nie jest wystarczająco funky bez OO? Przepraszam, że się odwracam i na pewno dziękuję za interesującą odpowiedź, ale posłużę się zwykłym starym stop () powyżej.
forkandwait

1
Teraz jest jeszcze więcej OO. :)
Iterator

3
@ws. Co jest takiego fajnego w R? plotwykreśla funkcję, try stop warnwszystko działa zgodnie z oczekiwaniami i prawie wszystko, co chcę zrobić, to jedna linijka.
izomorfizmy

4
Często „moc jednolinijkowych” nie jest dobrym wskaźnikiem dla języka. Dla wielu z nas czytelny i zrozumiały kod ma przewagę nad mniejszą liczbą wierszy. Rzeczywiście, wiele jest dla mnie niezrozumiałych, ponieważ jestem początkującym i staram się odpowiednio skalibrować oczekiwania. Ale inne języki sprawiają, że przejście od 0 do załatwiania spraw jest dość intuicyjne. Wydaje się również, że R wykształcił kulturę sprytnych, trudnych do odczytania linijek. Opowiadałbym się za kulturą kodu maksymalnie podobnego do angielskiego, który często mógłby być również jednowierszowy, jak Ruby.
Philip

6

W rzeczywistości funkcja stopifnotjest bardzo wygodna do implementacji kontroli poprawności w kodzie. Przyjmuje kilka wyrażeń logicznych i zwraca błąd, jeśli którekolwiek z nich ma wartość false.

Przykład: Aby sprawdzić, czy kolumna „c” istnieje w ramce danych „df”:

df <- data.frame(a = numeric(), b = numeric())
stopifnot(!is.null(df$c))

Spowoduje to wyświetlenie następującego błędu:

Error: !is.null(df$c) is not TRUE

Brzmi jak Python assert(...)...
Josiah Yoder

1

Możesz sprawdzić, czy kolumna istnieje i zrobić, co chcesz.
Załóżmy, że data.framenazwana df1i sprawdzona jest kolumna col1:

if(! any(grepl('^col1$',colnames(df1)))) stop("nonexistent column")

lub

if(! any(grepl('^col1$',colnames(df1)))) return(-1)

Na przykład

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.