J'obtiens une erreur lors de l'utilisation d'une fonction R que j'ai écrite:
Warning messages:
1: glm.fit: algorithm did not converge
2: glm.fit: algorithm did not converge
Ce que j'ai fait:
- Parcourez la fonction
- L'ajout d'impression pour savoir à quelle ligne l'erreur se produit suggère deux fonctions à ne pas utiliser
glm.fit
. Ils sontwindow()
etsave()
.
Mes approches générales incluent l'ajout print
et les stop
commandes, et le parcours d'une fonction ligne par ligne jusqu'à ce que je puisse localiser l'exception.
Cependant, il n'est pas clair pour moi d'utiliser ces techniques d'où provient cette erreur dans le code. Je ne suis même pas certain de quelles fonctions du code dépendent glm.fit
. Comment diagnostiquer ce problème?
options(warn = 2)
. Donc dans ce cas, le détail est essentiel pour répondre à votre question générale. +1 de moi.Réponses:
Je dirais que le débogage est une forme d'art, il n'y a donc pas de solution miracle. Il existe de bonnes stratégies de débogage dans n'importe quelle langue, et elles s'appliquent ici aussi (par exemple, lisez cet article sympa ). Par exemple, la première chose à faire est de reproduire le problème ... si vous ne pouvez pas faire cela, alors vous devez obtenir plus d'informations (par exemple avec la journalisation). Une fois que vous pouvez le reproduire, vous devez le réduire à la source.
Plutôt qu'un "truc", je dirais que j'ai une routine de débogage préférée:
traceback()
: cela vous montre où l'erreur s'est produite, ce qui est particulièrement utile si vous avez plusieurs fonctions imbriquées.options(error=recover)
; cela passe immédiatement en mode navigateur où l'erreur se produit, de sorte que vous pouvez parcourir l'espace de travail à partir de là.debug()
fonction et je parcours le script ligne par ligne.La meilleure nouvelle astuce dans R 2.10 (lorsque vous travaillez avec des fichiers de script) est d'utiliser les fonctions
findLineNum()
etsetBreakpoint()
.En guise de conclusion: en fonction de l'erreur, il est également très utile de définir
try()
outryCatch()
déclarations autour des appels de fonctions externes ( en particulier lorsqu'ils traitent avec les classes S4). Cela fournira parfois encore plus d'informations et vous donnera également plus de contrôle sur la façon dont les erreurs sont gérées au moment de l'exécution.Ces questions connexes comportent de nombreuses suggestions:
la source
browser()
pour quand il y a des erreurs qui ne déclenchent pas d'avertissements / erreurs (crédit: Roman Luštrik sur cette page). Un autre outil commebrowser()
?La meilleure solution que j'ai vue jusqu'à présent est:
http://www.biostat.jhsph.edu/%7Erpeng/docs/R-debug-tools.pdf
Quelqu'un est-il d'accord / en désaccord?
la source
Comme me l' a fait remarquer dans une autre question ,
Rprof()
etsummaryRprof()
sont beaux outils pour trouver des parties lentes de votre programme qui bénéficient de la puissance d'accélérer ou de passer à la mise en œuvre d'un C / C. Cela s'applique probablement davantage si vous effectuez un travail de simulation ou d'autres activités gourmandes en calcul ou en données. Leprofr
package peut aider à visualiser les résultats.Je suis un peu en train d'apprendre le débogage, donc une autre suggestion d' un autre fil :
options(warn=2)
pour traiter les avertissements comme des erreursVous pouvez également utiliser
options
pour vous plonger directement dans le feu de l'action lorsqu'une erreur ou un avertissement se produit, en utilisant la fonction de débogage préférée de votre choix. Par exemple:options(error=recover)
pour s'exécuterrecover()
lorsqu'une erreur se produit, comme Shane l'a noté (et comme indiqué dans le guide de débogage R. Ou toute autre fonction pratique que vous jugeriez utile d'exécuter.Et deux autres méthodes à partir de l'un des liens de @ Shane :
try()
pour renvoyer plus d'informations à ce sujet..inform=TRUE
(à partir du package plyr) comme option de la commande apply@JoshuaUlrich a également souligné une manière intéressante d'utiliser les capacités conditionnelles de la
browser()
commande classique pour activer / désactiver le débogage:browser(expr=isTRUE(getOption("myDebug")))
options(myDebug=TRUE)
myBrowse <- browser(expr=isTRUE(getOption("myDebug")))
puis appeler avecmyBrowse()
car il utilise des globaux.Ensuite, il y a les nouvelles fonctions disponibles dans R 2.10:
findLineNum()
prend un nom de fichier source et un numéro de ligne et renvoie la fonction et l'environnement. Cela semble utile lorsque voussource()
utilisez un fichier .R et qu'il renvoie une erreur à la ligne #n, mais vous devez savoir quelle fonction se trouve à la ligne #n.setBreakpoint()
prend un nom de fichier source et un numéro de ligne et y définit un point d'arrêtLe package codetools , et en particulier sa
checkUsage
fonction, peut être particulièrement utile pour détecter rapidement les erreurs de syntaxe et de style qu'un compilateur signalerait généralement (locals inutilisés, fonctions et variables globales non définies, correspondance partielle d'arguments, etc.).setBreakpoint()
est une interface plus conviviale pourtrace()
. Des détails sur les éléments internes de la façon dont cela fonctionne sont disponibles dans un article récent du R Journal .Si vous essayez de déboguer le package de quelqu'un d'autre, une fois que vous avez localisé le problème, vous pouvez écraser leurs fonctions avec
fixInNamespace
etassignInNamespace
, mais ne l'utilisez pas dans le code de production.Rien de tout cela ne devrait exclure les outils de débogage R standard éprouvés , dont certains sont ci-dessus et d'autres pas. En particulier, les outils de débogage post-mortem sont pratiques lorsque vous avez un tas de code chronophage que vous préférez ne pas réexécuter.
Enfin, pour les problèmes délicats qui ne semblent pas générer de message d'erreur, vous pouvez utiliser
options(error=dump.frames)
comme détaillé dans cette question: Erreur sans qu'une erreur ne soit généréela source
À un moment donné,
glm.fit
est appelé. Cela signifie que l' une des fonctions que vous appelez ou l' une des fonctions appelées par ces fonctions est en utilisant soitglm
,glm.fit
.De plus, comme je l'ai mentionné dans mon commentaire ci-dessus, c'est un avertissement et non une erreur , ce qui fait une grande différence. Vous ne pouvez déclencher aucun des outils de débogage de R à partir d'un avertissement (avec les options par défaut avant que quelqu'un ne me dise que je me trompe ;-).
Si nous modifions les options pour transformer les avertissements en erreurs, nous pouvons commencer à utiliser les outils de débogage de R. De
?options
nous avons:Alors si tu cours
puis exécutez votre code, R lancera une erreur. À quel moment, vous pourriez courir
pour voir la pile d'appels. Voici un exemple.
Ici, vous pouvez ignorer les cadres marqués
4:
et supérieurs. Nous voyons celafoo
appelébar
et cela abar
généré l'avertissement. Cela devrait vous montrer quelles fonctions appelaientglm.fit
.Si vous souhaitez maintenant déboguer cela, nous pouvons utiliser une autre option pour dire à R d'entrer dans le débogueur lorsqu'il rencontre une erreur, et comme nous avons fait des erreurs d'avertissement, nous obtiendrons un débogueur lorsque l'avertissement d'origine est déclenché. Pour cela, vous devez exécuter:
Voici un exemple:
Vous pouvez ensuite entrer dans l'un de ces cadres pour voir ce qui se passait lorsque l'avertissement a été émis.
Pour réinitialiser les options ci-dessus à leur valeur par défaut, entrez
En ce qui concerne l'avertissement spécifique que vous citez, il est fort probable que vous deviez autoriser plus d'itérations dans le code. Une fois que vous avez découvert ce qui appelle
glm.fit
, essayez de lui transmettre l'control
argument en utilisantglm.control
- voir?glm.control
.la source
Alors
browser()
,traceback()
etdebug()
entrez dans un bar, maistrace()
attend à l'extérieur et maintient le moteur en marche.En insérant
browser
quelque part dans votre fonction, l'exécution s'arrêtera et attendra votre entrée. Vous pouvez avancer en utilisant n(ou Enter), exécuter le bloc entier (itération) avec c, terminer la boucle / fonction en cours avec f, ou quitter avec Q; voir?browser
.Avec
debug
, vous obtenez le même effet qu'avec le navigateur, mais cela arrête l'exécution d'une fonction à son début. Les mêmes raccourcis s'appliquent. Cette fonction sera en mode «débogage» jusqu'à ce que vous la désactiviez en utilisantundebug
(c'est-à-dire qu'après l'debug(foo)
exécution de la fonction, ellefoo
passera en mode «débogage» à chaque fois jusqu'à ce que vous l'exécutiezundebug(foo)
).Une alternative plus transitoire est
debugonce
, qui supprimera le mode «débogage» de la fonction après la prochaine évaluation.traceback
vous donnera le flux d'exécution des fonctions jusqu'à l'endroit où quelque chose s'est mal passé (une erreur réelle).Vous pouvez insérer des bits de code (c'est-à-dire des fonctions personnalisées) dans des fonctions en utilisant
trace
, par exemplebrowser
. Ceci est utile pour les fonctions des packages et vous êtes trop paresseux pour obtenir le code source bien plié.la source
Ma stratégie générale ressemble à:
traceback()
pour voir rechercher des problèmes évidentsoptions(warn=2)
pour traiter les avertissements comme des erreursoptions(error=recover)
pour entrer dans la pile d'appels en cas d'erreurla source
Après avoir traversé toutes les étapes proposées ici , je viens d' apprendre que la mise
.verbose = TRUE
enforeach()
me donne aussi des tonnes d'informations utiles. En particulier,foreach(.verbose=TRUE)
montre exactement où une erreur se produit dans la boucle foreach, alorstraceback()
qu'elle ne regarde pas à l'intérieur de la boucle foreach.la source
Le débogueur de Mark Bravington qui est disponible sous forme de package
debug
sur CRAN est très bon et assez simple.Le code apparaît dans une fenêtre Tk en surbrillance afin que vous puissiez voir ce qui se passe et, bien sûr, vous pouvez en appeler un autre
mtrace()
dans une fonction différente.HTH
la source
J'aime la réponse de Gavin: je ne connaissais pas les options (erreur = récupérer). J'aime aussi utiliser le package 'debug' qui donne un moyen visuel de parcourir votre code.
À ce stade, il ouvre une fenêtre de débogage distincte montrant votre fonction, avec une ligne jaune indiquant où vous vous trouvez dans le code. Dans la fenêtre principale, le code entre en mode débogage, et vous pouvez continuer à appuyer sur Entrée pour parcourir le code (et il y a aussi d'autres commandes), et examiner les valeurs des variables, etc. La ligne jaune dans la fenêtre de débogage continue de se déplacer pour montrer où vous êtes dans le code. Une fois le débogage terminé, vous pouvez désactiver le traçage avec:
la source
Sur la base de la réponse que j'ai reçue ici , vous devez absolument vérifier le
options(error=recover)
paramètre. Lorsque cela est défini, en cas d'erreur, vous verrez du texte sur la console similaire à ce qui suit (traceback
sortie):À quel point vous pouvez choisir le "cadre" dans lequel entrer. Lorsque vous faites une sélection, vous serez mis en
browser()
mode:Et vous pouvez examiner l'environnement tel qu'il était au moment de l'erreur. Lorsque vous avez terminé, tapez
c
pour vous ramener au menu de sélection de cadre. Lorsque vous avez terminé, comme il vous le dit, tapez0
pour quitter.la source
J'ai donné cette réponse à une question plus récente, mais je l'ajoute ici par souci d'exhaustivité.
Personnellement, j'ai tendance à ne pas utiliser de fonctions de débogage. Je trouve souvent que cela cause autant de problèmes que cela en résout. De plus, venant d'un arrière-plan Matlab, j'aime pouvoir le faire dans un environnement de développement intégré (IDE) plutôt que de le faire dans le code. L'utilisation d'un IDE garde votre code propre et simple.
Pour R, j'utilise un IDE appelé "RStudio" ( http://www.rstudio.com ), qui est disponible pour Windows, Mac et Linux et est assez facile à utiliser.
Les versions de Rstudio depuis octobre 2013 environ (0.98ish?) Ont la possibilité d'ajouter des points d'arrêt dans les scripts et les fonctions: pour ce faire, il suffit de cliquer sur la marge gauche du fichier pour ajouter un point d'arrêt. Vous pouvez définir un point d'arrêt, puis passer en revue à partir de ce point. Vous avez également accès à toutes les données de cet environnement, vous pouvez donc essayer des commandes.
Voir http://www.rstudio.com/ide/docs/debugging/overview pour plus de détails. Si vous avez déjà installé Rstudio, vous devrez peut-être mettre à niveau - il s'agit d'une fonctionnalité relativement nouvelle (fin 2013).
Vous pouvez également trouver d'autres IDE qui ont des fonctionnalités similaires.
Certes, s'il s'agit d'une fonction intégrée, vous devrez peut-être recourir à certaines des suggestions faites par d'autres personnes dans cette discussion. Mais, si c'est votre propre code qui doit être corrigé, une solution basée sur l'IDE peut être exactement ce dont vous avez besoin.
la source
Pour déboguer des méthodes de classe de référence sans référence d'instance
la source
Je commence à penser que ne pas imprimer le numéro de ligne d'erreur - une exigence la plus élémentaire - PAR DEFAILT - est une sorte de blague dans R / Rstudio . La seule méthode fiable que j'ai trouvée pour trouver où une erreur s'est produite est de faire l'effort supplémentaire d'appeler traceback () et de voir la ligne du haut.
la source