Otrzymuję błąd podczas używania funkcji R, którą napisałem:
Warning messages:
1: glm.fit: algorithm did not converge
2: glm.fit: algorithm did not converge
Co zrobiłem:
- Przejdź przez funkcję
- Dodanie print, aby dowiedzieć się, w której linii występuje błąd, sugeruje dwie funkcje, których nie należy używać
glm.fit
. Sąwindow()
isave()
.
Moje ogólne podejście obejmuje dodawanie print
i stop
polecenia oraz przechodzenie przez funkcję wiersz po wierszu, aż będę mógł zlokalizować wyjątek.
Jednak nie jest dla mnie jasne, jeśli korzystam z tych technik, skąd ten błąd w kodzie pochodzi. Nie jestem nawet pewien, od jakich funkcji w kodzie zależą glm.fit
. Jak mam zdiagnozować ten problem?
options(warn = 2)
. W tym przypadku szczegóły są niezbędne, aby odpowiedzieć na twoje ogólne pytanie. +1 ode mnie.Odpowiedzi:
Powiedziałbym, że debugowanie to forma sztuki, więc nie ma wyraźnej srebrnej kuli. Istnieją dobre strategie debugowania w dowolnym języku i mają one zastosowanie również tutaj (np. Przeczytaj ten fajny artykuł ). Na przykład, pierwszą rzeczą jest odtworzenie problemu ... jeśli nie możesz tego zrobić, musisz uzyskać więcej informacji (np. Z logowaniem). Kiedy będziesz mógł go odtworzyć, musisz zredukować go do źródła.
Zamiast „sztuczki” powiedziałbym, że mam ulubioną procedurę debugowania:
traceback()
: to pokazuje, gdzie wystąpił błąd, co jest szczególnie przydatne, jeśli masz kilka zagnieżdżonych funkcji.options(error=recover)
; powoduje to natychmiastowe przełączenie w tryb przeglądarki, w którym występuje błąd, dzięki czemu można stamtąd przeglądać obszar roboczy.debug()
funkcji i przechodzę przez skrypt wiersz po wierszu.Najlepszą nową sztuczką w R 2.10 (podczas pracy z plikami skryptów) jest użycie funkcji
findLineNum()
isetBreakpoint()
.Na koniec: w zależności od błędu bardzo pomocne jest również ustawienie
try()
lubtryCatch()
instrukcje wokół wywołań funkcji zewnętrznych (szczególnie w przypadku klas S4). Czasami zapewnia to jeszcze więcej informacji, a także daje większą kontrolę nad sposobem obsługi błędów w czasie wykonywania.Te powiązane pytania mają wiele sugestii:
źródło
browser()
gdy występują błędy, które nie powodują ostrzeżeń / błędów (źródło: Roman Luštrik na tej stronie). Jakieś inne narzędziebrowser()
?Najlepsza solucja, jaką do tej pory widziałem, to:
http://www.biostat.jhsph.edu/%7Erpeng/docs/R-debug-tools.pdf
Czy ktoś się zgadza / nie zgadza?
źródło
Jak wskazano mi się kolejne pytanie ,
Rprof()
asummaryRprof()
są ładne narzędzia znaleźć powolne części swojego programu , że korzyści może z przyspieszenia lub przeprowadzce do realizacji C / C ++. Prawdopodobnie ma to większe zastosowanie, jeśli wykonujesz prace symulacyjne lub inne działania wymagające dużej mocy obliczeniowej lub danych.profr
Pakiet może pomóc w wizualizacji wyników.Jestem w trakcie nauki o debugowaniu, więc kolejna sugestia z innego wątku :
options(warn=2)
aby traktować ostrzeżenia jak błędyMożesz również użyć
options
swojej ulubionej, wybranej funkcji debugowania, aby rzucić się w wir akcji, gdy wystąpi błąd lub ostrzeżenie. Na przykład:options(error=recover)
do uruchomienia,recover()
gdy wystąpi błąd, jak zauważył Shane (i jak jest to udokumentowane w przewodniku po debugowaniu języka R.) Lub jakakolwiek inna przydatna funkcja, którą warto uruchomić.I jeszcze dwie metody z jednego z linków @ Shane'a :
try()
aby zwrócić więcej informacji na jej temat..inform=TRUE
Apply użyj (z pakietu plyr) jako opcji do polecenia Apply@JoshuaUlrich wskazał również zgrabny sposób wykorzystania warunkowych możliwości klasycznego
browser()
polecenia do włączania / wyłączania debugowania:browser(expr=isTRUE(getOption("myDebug")))
options(myDebug=TRUE)
myBrowse <- browser(expr=isTRUE(getOption("myDebug")))
a następnie zadzwonić z,myBrowse()
ponieważ używa globals.Następnie dostępne są nowe funkcje w R 2.10:
findLineNum()
pobiera nazwę pliku źródłowego i numer linii oraz zwraca funkcję i środowisko. Wydaje się to być pomocne, gdysource()
plik .R zwraca błąd w wierszu # n, ale musisz wiedzieć, jaka funkcja znajduje się w wierszu # n.setBreakpoint()
pobiera nazwę pliku źródłowego i numer linii i ustawia tam punkt przerwaniaCodetools pakiet, a zwłaszcza jego
checkUsage
funkcja może być szczególnie pomocny w szybko zbierając składni i błędy stylistyczne, że kompilator będzie typowo raportu (niewykorzystane mieszkańców, niezdefiniowane globalne funkcje i zmienne, częściowe dopasowanie argumentów, i tak dalej).setBreakpoint()
jest bardziej przyjaznym dla użytkownika interfejsem użytkownikatrace()
. Szczegółowe informacje na temat tego, jak to działa, można znaleźć w ostatnim artykule w R Journal .Jeśli próbujesz debugować pakiet innej osoby, po zlokalizowaniu problemu możesz nadpisać jego funkcje za pomocą
fixInNamespace
iassignInNamespace
, ale nie używaj tego w kodzie produkcyjnym.Nic z tego nie powinno wykluczać wypróbowanych i prawdziwych standardowych narzędzi do debugowania języka R , z których niektóre są powyżej, a inne nie. W szczególności narzędzia do debugowania post-mortem są przydatne, gdy masz czasochłonny pakiet kodu, którego wolisz nie uruchamiać ponownie.
Wreszcie, w przypadku trudnych problemów, które nie wydają się generować komunikatu o błędzie, możesz użyć
options(error=dump.frames)
szczegółów w tym pytaniu: Błąd bez zgłaszania błęduźródło
W pewnym momencie
glm.fit
jest wzywany. Oznacza to, że jedną z funkcji zadzwonić lub jedną z funkcji wywoływanych przez te funkcje korzystają alboglm
,glm.fit
.Ponadto, jak wspomniałem w moim komentarzu powyżej, jest to ostrzeżenie, a nie błąd , co robi dużą różnicę. Nie możesz wywołać żadnego narzędzia debugowania języka R z ostrzeżenia (z domyślnymi opcjami, zanim ktoś mi powie, że się mylę ;-).
Jeśli zmienimy opcje, aby zamienić ostrzeżenia w błędy, możemy zacząć używać narzędzi do debugowania R. Od
?options
mamy:Więc jeśli uciekniesz
następnie uruchom kod, R zgłosi błąd. W którym momencie możesz biec
aby zobaczyć stos wywołań. Oto przykład.
Tutaj możesz zignorować ramki oznaczone
4:
i wyższe. Widzimy, żefoo
nazywabar
, abar
generowane ostrzeżenie. To powinno pokazać, które funkcje wywoływałyglm.fit
.Jeśli teraz chcesz to debugować, możemy skorzystać z innej opcji, aby powiedzieć R, aby wszedł do debugera, gdy napotka błąd, a ponieważ popełniliśmy błędy ostrzeżeń, po uruchomieniu oryginalnego ostrzeżenia otrzymamy debuger. W tym celu powinieneś uruchomić:
Oto przykład:
Następnie możesz wejść do dowolnej z tych ramek, aby zobaczyć, co się działo, gdy wyświetlono ostrzeżenie.
Aby zresetować powyższe opcje do wartości domyślnych, wprowadź
Jeśli chodzi o konkretne ostrzeżenie, które cytujesz, jest wysoce prawdopodobne, że musisz zezwolić na więcej iteracji w kodzie. Kiedy już dowiesz się, co wywołuje
glm.fit
, zastanów się, jak przekazaćcontrol
argument, używającglm.control
- patrz?glm.control
.źródło
Tak
browser()
,traceback()
idebug()
iść do baru, aletrace()
czeka na zewnątrz i utrzymuje pracę silnika.Wstawiając
browser
gdzieś w swojej funkcji, wykonanie zatrzyma się i będzie czekać na dane wejściowe. Możesz przejść do przodu za pomocą n(lub Enter), uruchomić cały fragment (iterację) za pomocą c, zakończyć bieżącą pętlę / funkcję za pomocą flub zakończyć za pomocą Q; zobacz?browser
.W przypadku
debug
uzyskuje się ten sam efekt, co w przypadku przeglądarki, ale powoduje to zatrzymanie wykonywania funkcji na jej początku. Obowiązują te same skróty. Ta funkcja będzie w trybie „debugowania”, dopóki nie wyłączysz jej za pomocąundebug
(to znaczy, podebug(foo)
uruchomieniu funkcji zafoo
każdym razem, aż do jej uruchomienia, wejdzie w tryb „debugowania”undebug(foo)
).Bardziej przejściową alternatywą jest
debugonce
usunięcie trybu „debugowania” z funkcji po jej następnym oszacowaniu.traceback
da ci przepływ wykonywania funkcji aż do miejsca, w którym coś poszło nie tak (rzeczywisty błąd).Możesz wstawiać bity kodu (tj. Funkcje niestandardowe) w funkcjach używając
trace
na przykładbrowser
. Jest to przydatne w przypadku funkcji z pakietów i jesteś zbyt leniwy, aby uzyskać ładnie zwinięty kod źródłowy.źródło
Moja ogólna strategia wygląda następująco:
traceback()
aby zobaczyć, szukać oczywistych problemówoptions(warn=2)
aby traktować ostrzeżenia jak błędyoptions(error=recover)
wchodzenie na stos wywołań w przypadku błęduźródło
Po przejściu przez wszystkie etapy proponowane tutaj Właśnie dowiedziałem się, że ustawienie
.verbose = TRUE
wforeach()
również daje mi mnóstwo przydatnych informacji. W szczególnościforeach(.verbose=TRUE)
pokazuje dokładnie, gdzie występuje błąd w pętli foreach, atraceback()
nie zagląda do pętli foreach.źródło
Debugger Marka Bravingtona, który jest dostępny jako pakiet
debug
na CRAN, jest bardzo dobry i całkiem prosty.Kod pojawia się w podświetlonym oknie Tk, więc możesz zobaczyć, co się dzieje i oczywiście możesz zadzwonić do innego
mtrace()
będąc w innej funkcji.HTH
źródło
Podoba mi się odpowiedź Gavina: nie wiedziałem o opcjach (błąd = odzyskać). Lubię też używać pakietu „debug”, który zapewnia wizualny sposób przechodzenia przez kod.
W tym momencie otwiera się osobne okno debugowania pokazujące twoją funkcję, z żółtą linią pokazującą, gdzie jesteś w kodzie. W głównym oknie kod przechodzi w tryb debugowania i możesz wciskać enter, aby przechodzić przez kod (są też inne polecenia) i sprawdzać wartości zmiennych itp. Żółta linia w oknie debugowania przesuwa się, aby pokazać, gdzie jesteś w kodzie. Po zakończeniu debugowania możesz wyłączyć śledzenie za pomocą:
źródło
W oparciu o odpowiedź, którą tutaj otrzymałem , zdecydowanie powinieneś sprawdzić
options(error=recover)
ustawienie. Gdy ta opcja jest ustawiona, po napotkaniu błędu na konsoli zostanie wyświetlony tekst podobny do następującego (traceback
dane wyjściowe):W którym momencie możesz wybrać, do której „ramki” chcesz wejść. Kiedy dokonasz wyboru, przejdziesz do
browser()
trybu:Możesz też zbadać środowisko, jakie było w momencie wystąpienia błędu. Kiedy skończysz, wpisz
c
tekst, aby wrócić do menu wyboru ramek. Jak skończysz, wpisz,0
aby zakończyć.źródło
Udzieliłem tej odpowiedzi na nowsze pytanie, ale dodam ją tutaj dla kompletności.
Osobiście nie używam funkcji do debugowania. Często stwierdzam, że powoduje to tyle samo problemów, co rozwiązuje. Ponadto, wywodząc się ze środowiska Matlab, wolę móc to robić w zintegrowanym środowisku programistycznym (IDE), zamiast robić to w kodzie. Korzystanie ze środowiska IDE sprawia, że kod jest czysty i prosty.
W R używam IDE o nazwie „RStudio” ( http://www.rstudio.com ), które jest dostępne dla systemów Windows, Mac i Linux i jest dość łatwe w użyciu.
Wersje Rstudio od około października 2013 r. (0.98ish?) Mają możliwość dodawania punktów przerwania w skryptach i funkcjach: w tym celu wystarczy kliknąć lewy margines pliku, aby dodać punkt przerwania. Możesz ustawić punkt przerwania, a następnie przejść od tego punktu. Masz również dostęp do wszystkich danych w tym środowisku, więc możesz wypróbować polecenia.
Szczegółowe informacje można znaleźć pod adresem http://www.rstudio.com/ide/docs/debugging/overview . Jeśli masz już zainstalowane oprogramowanie Rstudio, może być konieczna aktualizacja - jest to stosunkowo nowa (koniec 2013 r.) Funkcja.
Możesz również znaleźć inne IDE, które mają podobną funkcjonalność.
Trzeba przyznać, że jeśli jest to funkcja wbudowana, być może będziesz musiał skorzystać z niektórych sugestii przedstawionych przez inne osoby w tej dyskusji. Ale jeśli jest to Twój własny kod, który wymaga naprawy, rozwiązanie oparte na IDE może być właśnie tym, czego potrzebujesz.
źródło
Aby debugować metody klasy referencyjnej bez odwołania do instancji
źródło
Zaczynam myśleć, że niewypisanie numeru linii błędu - najbardziej podstawowy wymóg - BY DEFAILT - to jakiś żart w R / Rstudio . Jedyną niezawodną metodą, jaką znalazłem, aby znaleźć miejsce wystąpienia błędu, jest wykonanie dodatkowego wysiłku w postaci wywołania funkcji traceback () i zobaczenie górnej linii.
źródło