Ich erhalte eine Fehlermeldung, wenn ich eine von mir geschriebene R-Funktion verwende:
Warning messages:
1: glm.fit: algorithm did not converge
2: glm.fit: algorithm did not converge
Was habe ich getan:
- Schritt durch die Funktion
- Das Hinzufügen von print, um herauszufinden, in welcher Zeile der Fehler auftritt, schlägt zwei Funktionen vor, die nicht verwendet werden sollten
glm.fit
. Sie sindwindow()
undsave()
.
Meine allgemeinen Ansätze umfassen das Hinzufügen print
und stop
Befehlen sowie das zeilenweise Durchlaufen einer Funktion, bis ich die Ausnahme finden kann.
Es ist mir jedoch nicht klar, mit welchen Techniken dieser Fehler im Code auftritt. Ich bin mir nicht einmal sicher, von welchen Funktionen im Code abhängt glm.fit
. Wie gehe ich vor, um dieses Problem zu diagnostizieren?
options(warn = 2)
. In diesem Fall ist das Detail für die Beantwortung Ihrer allgemeinen Frage von entscheidender Bedeutung. +1 von mir.Antworten:
Ich würde sagen, dass das Debuggen eine Kunstform ist, also gibt es keine klare Silberkugel. Es gibt gute Strategien zum Debuggen in jeder Sprache, und diese gelten auch hier (z. B. lesen Sie diesen schönen Artikel ). Das erste, was Sie tun müssen, ist beispielsweise, das Problem zu reproduzieren. Wenn Sie dies nicht tun können, müssen Sie weitere Informationen abrufen (z. B. bei der Protokollierung). Sobald Sie es reproduzieren können, müssen Sie es auf die Quelle reduzieren .
Anstelle eines "Tricks" würde ich sagen, dass ich eine bevorzugte Debugging-Routine habe:
traceback()
: Dies zeigt Ihnen, wo der Fehler aufgetreten ist. Dies ist besonders nützlich, wenn Sie mehrere verschachtelte Funktionen haben.options(error=recover)
; Dadurch wird sofort in den Browsermodus gewechselt, in dem der Fehler auftritt, sodass Sie von dort aus den Arbeitsbereich durchsuchen können.debug()
Funktion und gehe das Skript Zeile für Zeile durch.Der beste neue Trick in R 2.10 (beim Arbeiten mit Skriptdateien) ist die Verwendung der Funktionen
findLineNum()
undsetBreakpoint()
.Als letzter Kommentar: Abhängig vom Fehler ist es auch sehr hilfreich, externe Funktionsaufrufe festzulegen
try()
odertryCatch()
Anweisungen zu geben (insbesondere beim Umgang mit S4-Klassen). Dadurch erhalten Sie manchmal noch mehr Informationen und können besser steuern, wie Fehler zur Laufzeit behandelt werden.Diese verwandten Fragen haben viele Vorschläge:
quelle
browser()
für den Fall, dass es Fehler gibt, die keine Warnungen / Fehler auslösen (Bildnachweis: Roman Luštrik auf dieser Seite). Irgendein anderes Tool wiebrowser()
?Der beste Durchgang, den ich bisher gesehen habe, ist:
http://www.biostat.jhsph.edu/%7Erpeng/docs/R-debug-tools.pdf
Ist jemand einverstanden / nicht einverstanden?
quelle
Wie in mir wies darauf hin , eine andere Frage ,
Rprof()
undsummaryRprof()
sind nette Werkzeuge zu langsamen Teile des Programms zu finden , dass könnte profitieren von beschleunigen oder Umzug in eine C / C ++ Implementierung. Dies gilt wahrscheinlich mehr, wenn Sie Simulationsarbeiten oder andere rechen- oder datenintensive Aktivitäten ausführen. Dasprofr
Paket kann dabei helfen, die Ergebnisse zu visualisieren.Ich bin gerade dabei, etwas über das Debuggen zu lernen, also ein weiterer Vorschlag aus einem anderen Thread :
options(warn=2)
, dass Warnungen wie Fehler behandelt werdenSie können Sie auch verwenden
options
, um Sie direkt in die Hitze der Aktion zu versetzen, wenn ein Fehler oder eine Warnung auftritt, und dabei Ihre bevorzugte Debugging-Funktion verwenden. Zum Beispiel:options(error=recover)
diese Option so ein , dass sie ausgeführt wird,recover()
wenn ein Fehler auftritt, wie Shane festgestellt hat (und wie im R-Debugging-Handbuch dokumentiert) .Und noch zwei Methoden von einem der Links von @ Shane :
try()
, um weitere Informationen zurückzugeben..inform=TRUE
Apply- Funktionen (aus dem Plyr-Paket) als Option für den Apply-Befehl@JoshuaUlrich wies auch auf eine gute Möglichkeit hin, die bedingten Fähigkeiten des klassischen
browser()
Befehls zum Ein- und Ausschalten des Debuggens zu nutzen:browser(expr=isTRUE(getOption("myDebug")))
options(myDebug=TRUE)
myBrowse <- browser(expr=isTRUE(getOption("myDebug")))
und dann mit aufrufen,myBrowse()
da er Globals verwendet.Dann gibt es die neuen Funktionen in R 2.10:
findLineNum()
Nimmt einen Quelldateinamen und eine Zeilennummer und gibt die Funktion und Umgebung zurück. Dies scheint hilfreich zu sein, wenn Siesource()
eine .R-Datei verwenden und in Zeile #n einen Fehler zurückgibt. Sie müssen jedoch wissen, welche Funktion sich in Zeile #n befindet.setBreakpoint()
Nimmt einen Quelldateinamen und eine Zeilennummer und setzt dort einen HaltepunktDas Codetools- Paket und insbesondere seine
checkUsage
Funktion können besonders hilfreich sein, um Syntax- und Stilfehler, die ein Compiler normalerweise meldet (nicht verwendete lokale Elemente , undefinierte globale Funktionen und Variablen, partielle Argumentübereinstimmung usw.), schnell zu erkennen.setBreakpoint()
ist ein benutzerfreundlicheres Frontendtrace()
. Details zu den Interna, wie dies funktioniert, finden Sie in einem kürzlich erschienenen Artikel im R Journal .Wenn Sie versuchen, das Paket eines anderen zu debuggen, können Sie, sobald Sie das Problem gefunden haben , dessen Funktionen mit
fixInNamespace
undassignInNamespace
überschreiben, verwenden Sie dies jedoch nicht im Produktionscode.Nichts davon sollte die bewährten Standard-R-Debugging-Tools ausschließen , von denen einige oben stehen und andere nicht. Insbesondere die Post-Mortem-Debugging-Tools sind praktisch, wenn Sie eine zeitaufwändige Menge an Code haben, die Sie lieber nicht erneut ausführen möchten.
Schließlich können Sie für knifflige Probleme, bei denen keine Fehlermeldung ausgegeben wird, Folgendes verwenden
options(error=dump.frames)
: Fehler, ohne dass ein Fehler ausgelöst wirdquelle
Irgendwann
glm.fit
wird gerufen. Das bedeutet, dass eine der von Ihnen aufgerufenen Funktionen oder eine der von diesen Funktionen aufgerufenen Funktionen entweder Folgendes verwendetglm
:glm.fit
.Wie ich oben in meinem Kommentar erwähne, ist dies eine Warnung, kein Fehler , der einen großen Unterschied macht. Sie können keines der Debugging-Tools von R über eine Warnung auslösen (mit Standardoptionen, bevor mir jemand sagt, dass ich falsch liege ;-).
Wenn wir die Optionen ändern, um Warnungen in Fehler umzuwandeln, können wir die Debugging-Tools von R verwenden. Von haben
?options
wir:Also wenn du rennst
Führen Sie dann Ihren Code aus. R gibt einen Fehler aus. An welchem Punkt könnten Sie laufen
um den Aufrufstapel zu sehen. Hier ist ein Beispiel.
Hier können Sie die markierten
4:
und höheren Frames ignorieren . Wir sehen, dass diesfoo
aufgerufen wurdebar
undbar
die Warnung generiert wurde. Das sollte Ihnen zeigen, welche Funktionen aufgerufen wurdenglm.fit
.Wenn Sie dies jetzt debuggen möchten, können Sie sich an eine andere Option wenden, um R anzuweisen, den Debugger einzugeben, wenn ein Fehler auftritt. Da wir Warnfehler gemacht haben, erhalten wir einen Debugger, wenn die ursprüngliche Warnung ausgelöst wird. Dafür solltest du laufen:
Hier ist ein Beispiel:
Sie können dann in einen dieser Frames treten, um zu sehen, was passiert ist, als die Warnung ausgelöst wurde.
Geben Sie ein, um die oben genannten Optionen auf ihre Standardeinstellungen zurückzusetzen
Für die spezifische Warnung, die Sie zitieren, ist es sehr wahrscheinlich, dass Sie mehr Iterationen im Code zulassen müssen. Wenn Sie herausgefunden haben, was aufgerufen wird
glm.fit
, können Sie herausfinden, wie Sie dascontrol
Argument mitglm.control
- siehe?glm.control
.quelle
Also
browser()
,traceback()
unddebug()
geh in eine Bar,trace()
warte aber draußen und lasse den Motor laufen.Durch Einfügen
browser
irgendwo in Ihre Funktion wird die Ausführung angehalten und auf Ihre Eingabe gewartet. Sie können mit n(oder Enter) vorwärts gehen , den gesamten Block (Iteration) mit ausführen c, die aktuelle Schleife / Funktion mit fbeenden oder mit beenden Q. siehe?browser
.Mit erhalten
debug
Sie den gleichen Effekt wie mit dem Browser, dies stoppt jedoch die Ausführung einer Funktion am Anfang. Es gelten die gleichen Verknüpfungen. Diese Funktion befindet sich in einem "Debug" -Modus, bis Sie sie mit deaktivierenundebug
(dh nachdemdebug(foo)
die Funktion ausgeführt wurde, wechseltfoo
sie jedes Mal in den "Debug" -Modus, bis Sie sie ausführenundebug(foo)
).Eine vorübergehende Alternative ist
debugonce
, dass der "Debug" -Modus nach der nächsten Auswertung aus der Funktion entfernt wird.traceback
gibt Ihnen den Ablauf der Ausführung von Funktionen bis zu dem Punkt, an dem etwas schief gelaufen ist (ein tatsächlicher Fehler).Sie können Code - Bits (dh benutzerdefinierte Funktionen) in Funktionen einsetzen
trace
, zum Beispielbrowser
. Dies ist nützlich für Funktionen aus Paketen und Sie sind zu faul, um den schön gefalteten Quellcode zu erhalten.quelle
Meine allgemeine Strategie sieht so aus:
traceback()
den Vorgang aus, um nach offensichtlichen Problemen zu suchenoptions(warn=2)
, dass Warnungen wie Fehler behandelt werdenoptions(error=recover)
, dass Sie bei einem Fehler in den Aufrufstapel eintretenquelle
Nachdem alle Schritte hier vorgeschlagen durchlaufen ich gerade gelernt , dass Einstellung
.verbose = TRUE
inforeach()
mir Tonnen von nützlichen Informationen auch gibt.foreach(.verbose=TRUE)
Zeigt insbesondere genau an, wo ein Fehler innerhalb der foreach-Schleife auftritt, währendtraceback()
nicht innerhalb der foreach-Schleife geschaut wird.quelle
Mark Bravingtons Debugger, der als Paket
debug
auf CRAN verfügbar ist, ist sehr gut und ziemlich einfach.Der Code wird in einem hervorgehobenen Tk-Fenster angezeigt, sodass Sie sehen können, was los ist, und natürlich einen anderen anrufen können
mtrace()
in einer anderen Funktion einen anderen .HTH
quelle
Ich mag Gavins Antwort: Ich wusste nichts über Optionen (Fehler = Wiederherstellen). Ich verwende auch gerne das 'Debug'-Paket, das eine visuelle Möglichkeit bietet, Ihren Code zu durchlaufen.
Zu diesem Zeitpunkt wird ein separates Debug-Fenster geöffnet, in dem Ihre Funktion angezeigt wird. Eine gelbe Linie zeigt an, wo Sie sich im Code befinden. Im Hauptfenster wechselt der Code in den Debug-Modus, und Sie können weiterhin die Eingabetaste drücken, um den Code zu durchlaufen (und es gibt auch andere Befehle) und Variablenwerte usw. zu untersuchen. Die gelbe Linie im Debug-Fenster bewegt sich weiter, um anzuzeigen, wo Sie sind im Code. Wenn Sie mit dem Debuggen fertig sind, können Sie die Ablaufverfolgung deaktivieren mit:
quelle
Basierend auf der Antwort, die ich hier erhalten habe , sollten Sie auf jeden Fall die
options(error=recover)
Einstellung überprüfen . Wenn dies festgelegt ist, wird bei Auftreten eines Fehlers auf der Konsole ein Text angezeigt, der dem folgenden ähnelt (traceback
Ausgabe):An welchem Punkt können Sie auswählen, welchen "Frame" Sie eingeben möchten. Wenn Sie eine Auswahl treffen, werden Sie in den
browser()
Modus versetzt:Und Sie können die Umgebung so untersuchen, wie sie zum Zeitpunkt des Fehlers war. Wenn Sie fertig sind
c
, geben Sie ein, um zum Rahmenauswahlmenü zurückzukehren. Wenn Sie fertig sind, geben Sie0
zum Beenden ein.quelle
Ich habe diese Antwort auf eine neuere Frage gegeben, füge sie der Vollständigkeit halber hier hinzu.
Persönlich neige ich dazu, keine Funktionen zum Debuggen zu verwenden. Ich finde oft, dass dies so viel Ärger verursacht, wie es löst. Da ich aus einem Matlab-Hintergrund komme, mag ich es, dies in einer integrierten Entwicklungsumgebung (IDE) zu tun, anstatt dies im Code zu tun. Die Verwendung einer IDE hält Ihren Code sauber und einfach.
Für R verwende ich eine IDE namens "RStudio" ( http://www.rstudio.com ), die für Windows, Mac und Linux verfügbar und recht einfach zu verwenden ist.
Versionen von Rstudio seit etwa Oktober 2013 (0.98ish?) Können Haltepunkte in Skripten und Funktionen hinzufügen: Klicken Sie dazu einfach auf den linken Rand der Datei, um einen Haltepunkt hinzuzufügen. Sie können einen Haltepunkt festlegen und von diesem Punkt an fortfahren. Sie haben auch Zugriff auf alle Daten in dieser Umgebung, sodass Sie Befehle ausprobieren können.
Weitere Informationen finden Sie unter http://www.rstudio.com/ide/docs/debugging/overview . Wenn Sie Rstudio bereits installiert haben, müssen Sie möglicherweise ein Upgrade durchführen. Dies ist eine relativ neue Funktion (Ende 2013).
Möglicherweise finden Sie auch andere IDEs mit ähnlichen Funktionen.
Zugegeben, wenn es sich um eine integrierte Funktion handelt, müssen Sie möglicherweise auf einige der Vorschläge zurückgreifen, die andere Personen in dieser Diskussion gemacht haben. Wenn jedoch Ihr eigener Code repariert werden muss, ist eine IDE-basierte Lösung möglicherweise genau das, was Sie benötigen.
quelle
Debuggen von Referenzklassenmethoden ohne Instanzreferenz
quelle
Ich fange an zu denken, dass es eine Art Witz in R / Rstudio ist, keine Fehlerzeilennummer zu drucken - eine Grundvoraussetzung - BY DEFAILT . Die einzige zuverlässige Methode, die ich gefunden habe, um herauszufinden, wo ein Fehler aufgetreten ist, besteht darin, sich zusätzlich darum zu bemühen, traceback () aufzurufen und die oberste Zeile anzuzeigen .
quelle