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.

forkandwait
źródło
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.

Dirk Eddelbuettel
źródło
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
48

Prosty przykład:

f <- function(a, b){ 

    if (a == 0){ 
            stop("error message")
    }
 }
Christian Herrera Jiménez
źródło
Tutaj stackoverflow.com/a/23917007/54964 dla zmiennych w komunikatach o błędach.
Léo Léopold Hertz 준영
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/

Shane
źródło
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
Chris
źródło
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

xm1
źródło