Я получаю сообщение об ошибке при использовании написанной мной функции R:
Warning messages:
1: glm.fit: algorithm did not converge
2: glm.fit: algorithm did not converge
Что я наделал:
- Пройдите через функцию
- Добавление print, чтобы узнать, в какой строке происходит ошибка, предлагает две функции, которые не следует использовать
glm.fit
. Они естьwindow()
иsave()
.
Мои общие подходы включают добавление print
и stop
команды, а также пошаговое выполнение функции построчно, пока я не найду исключение.
Однако мне неясно, используя эти методы, откуда эта ошибка в коде. Я даже не уверен, от каких функций в коде зависит glm.fit
. Как мне диагностировать эту проблему?
options(warn = 2)
. Так что в этом случае детали важны для ответа на ваш общий вопрос. +1 от меня.Ответы:
Я бы сказал, что отладка - это искусство, поэтому нет чистой серебряной пули. Есть хорошие стратегии для отладки на любом языке, и они применимы и здесь (например, прочтите эту хорошую статью ). Например, первое, что нужно сделать, - это воспроизвести проблему ... если вы не можете этого сделать, вам нужно получить дополнительную информацию (например, с помощью регистрации). Как только вы сможете воспроизвести его, вам нужно свести его к источнику.
Вместо «уловки» я бы сказал, что у меня есть любимая процедура отладки:
traceback()
: который показывает вам, где произошла ошибка, что особенно полезно, если у вас есть несколько вложенных функций.options(error=recover)
; это немедленно переключается в режим браузера, где возникает ошибка, поэтому вы можете просматривать рабочее пространство оттуда.debug()
функцию и шаг за шагом просматриваю скрипт.Лучший новый трюк в R 2.10 (при работе с файлами сценариев) заключается в использовании
findLineNum()
иsetBreakpoint()
функции.В качестве заключительного комментария: в зависимости от ошибки также очень полезно установить операторы
try()
ortryCatch()
вокруг вызовов внешних функций (особенно при работе с классами S4). Иногда это дает даже больше информации, а также дает вам больше контроля над обработкой ошибок во время выполнения.В этих связанных вопросах есть много предложений:
источник
browser()
когда есть ошибки, которые не вызывают предупреждений / ошибок (кредит: Роман Луштрик на этой странице). Любой другой инструмент нравитсяbrowser()
?Лучшее прохождение, которое я видел до сих пор:
http://www.biostat.jhsph.edu/%7Erpeng/docs/R-debug-tools.pdf
Кто-нибудь согласен / не согласен?
источник
Как было отмечено, для меня в другом вопросе ,
Rprof()
иsummaryRprof()
есть хорошие инструменты , чтобы найти медленные части вашей программы , которые могли бы извлечь выгоду от ускорения или перехода к реализации С / С ++. Это, вероятно, больше применимо, если вы выполняете симуляцию или другую деятельность, требующую большого объема вычислений или данных.profr
Пакет может помочь визуализировать результаты.Я немного начинаю изучать отладку, поэтому еще одно предложение из другого потока :
options(warn=2)
для обработки предупреждений как ошибокВы также можете использовать
options
эту функцию, чтобы сразу погрузиться в бой при возникновении ошибки или предупреждения, используя вашу любимую функцию отладки по вашему выбору. Например:options(error=recover)
для запускаrecover()
при возникновении ошибки, как отметил Шейн (и , как документирован в R отладка руководства . Или любая другая удобная функцию , которую вы нашли бы полезно иметь бежать.И еще два метода из одной из ссылок @ Shane :
try()
чтобы получить дополнительную информацию о нем..inform=TRUE
(из пакета plyr) как параметр команды apply@JoshuaUlrich также указал на изящный способ использования условных возможностей классической
browser()
команды для включения / выключения отладки:browser(expr=isTRUE(getOption("myDebug")))
options(myDebug=TRUE)
myBrowse <- browser(expr=isTRUE(getOption("myDebug")))
а затем вызвать с,myBrowse()
поскольку он использует глобальные переменные.Затем в R 2.10 доступны новые функции:
findLineNum()
берет имя исходного файла и номер строки и возвращает функцию и среду. Это кажется полезным, если у васsource()
есть файл .R, и он возвращает ошибку в строке #n, но вам нужно знать, какая функция находится в строке #n.setBreakpoint()
берет имя исходного файла и номер строки и устанавливает там точку остановаПакет codetools и, в частности, его
checkUsage
функция могут быть особенно полезны для быстрого выявления синтаксических и стилистических ошибок, о которых обычно сообщает компилятор (неиспользуемые локальные переменные, неопределенные глобальные функции и переменные, частичное сопоставление аргументов и т. Д.).setBreakpoint()
- это более удобный интерфейс дляtrace()
. Подробности о том, как это работает, доступны в недавней статье R Journal .Если вы пытаетесь отлаживать чужой пакет, обнаружив проблему, вы можете перезаписать его функции с помощью
fixInNamespace
иassignInNamespace
, но не используйте это в производственном коде.Ничто из этого не должно препятствовать использованию проверенных временем стандартных инструментов отладки R , некоторые из которых указаны выше, а другие - нет. В частности, инструменты посмертной отладки удобны, когда у вас есть трудоемкий набор кода, который вы не хотели бы запускать повторно.
Наконец, для сложных проблем, которые, похоже, не вызывают сообщения об ошибке, вы можете использовать,
options(error=dump.frames)
как описано в этом вопросе: Ошибка без появления ошибкиисточник
В какой-то момент
glm.fit
вызывается. Это означает , что одна из функций вы называете или одной из функций , вызываемых этими функциями используется либоglm
,glm.fit
.Кроме того, как я упоминал в своем комментарии выше, это предупреждение, а не ошибка , что имеет большое значение. Вы не можете запустить какие-либо инструменты отладки R из предупреждения (с параметрами по умолчанию, прежде чем кто-то скажет мне, что я ошибаюсь ;-).
Если мы изменим параметры, чтобы превратить предупреждения в ошибки, мы можем начать использовать инструменты отладки R. От
?options
нас есть:Итак, если вы бежите
затем запустите свой код, R выдаст ошибку. В этот момент вы можете запустить
чтобы увидеть стек вызовов. Вот пример.
Здесь можно игнорировать кадры, отмеченные
4:
и выше. Мы видим, что былfoo
вызванbar
иbar
сгенерировано предупреждение. Это должно показать вам, какие функции вызывалисьglm.fit
.Если теперь вы хотите отладить это, мы можем обратиться к другому варианту, чтобы сообщить R, чтобы он входил в отладчик при обнаружении ошибки, и, поскольку мы сделали предупреждения об ошибках, мы получим отладчик, когда сработает исходное предупреждение. Для этого вам следует запустить:
Вот пример:
Затем вы можете перейти в любой из этих кадров, чтобы увидеть, что происходило, когда было выдано предупреждение.
Чтобы восстановить значения по умолчанию для указанных выше параметров, введите
Что касается конкретного предупреждения, которое вы цитируете, весьма вероятно, что вам нужно разрешить больше итераций в коде. Как только вы узнали, что вызывает
glm.fit
, подумайте, как передать емуcontrol
аргумент, используяglm.control
- см?glm.control
.источник
Так
browser()
,traceback()
иdebug()
ходить в бар, ноtrace()
ждем снаружи и не отпускаем мотор.Если вставить что-
browser
нибудь в свою функцию, выполнение остановится и будет ждать вашего ввода. Вы можете двигаться вперед с помощью n(или Enter), запустить весь фрагмент (итерацию) с помощью c, завершить текущий цикл / функцию с помощью fили выйти с помощью Q; видеть?browser
.С помощью
debug
вы получаете тот же эффект, что и с браузером, но это останавливает выполнение функции в ее начале. Применяются те же ярлыки. Эта функция будет находиться в режиме «отладки», пока вы не отключите ее с помощьюundebug
(то есть послеdebug(foo)
запуска функцияfoo
будет переходить в режим «отладки» каждый раз, пока вы не запуститеundebug(foo)
).Более временной альтернативой является
debugonce
удаление режима «отладки» из функции после ее следующей оценки.traceback
предоставит вам последовательность выполнения функций вплоть до того, где что-то пошло не так (фактическая ошибка).Вы можете вставлять биты кода (т.е. пользовательские функции) в функции
trace
, например, используяbrowser
. Это полезно для функций из пакетов, и вам лень получить красиво свернутый исходный код.источник
Моя общая стратегия выглядит так:
traceback()
ищи очевидные проблемыoptions(warn=2)
для обработки предупреждений как ошибокoptions(error=recover)
переход в стек вызовов при ошибкеисточник
После прохождения через все шаги , предложенные здесь , я только что узнал , что установка
.verbose = TRUE
вforeach()
тоже дает мне тонны полезной информации. В частности,foreach(.verbose=TRUE)
показывает, где именно происходит ошибка внутри цикла foreach, ноtraceback()
не заглядывает внутрь цикла foreach.источник
Отладчик Марка Бравингтона, доступный в виде пакета
debug
на CRAN, очень хорош и довольно прост.Код появляется в выделенном окне Tk, чтобы вы могли видеть, что происходит, и, конечно, вы можете позвонить другому
mtrace()
находясь в другой функции.НТН
источник
Мне нравится ответ Гэвина: я не знал о параметрах (ошибка = восстановление). Мне также нравится использовать пакет «отладка», который дает визуальный способ пошагового выполнения кода.
На этом этапе открывается отдельное окно отладки, показывающее вашу функцию, с желтой линией, показывающей, где вы находитесь в коде. В главном окне код переходит в режим отладки, и вы можете продолжать нажимать Enter для пошагового выполнения кода (а есть и другие команды), проверки значений переменных и т. Д. Желтая линия в окне отладки продолжает двигаться, показывая, где вы в коде. После завершения отладки вы можете отключить трассировку с помощью:
источник
Основываясь на ответе, который я получил здесь , вам обязательно стоит проверить
options(error=recover)
настройку. Когда это установлено, при обнаружении ошибки вы увидите текст на консоли, подобный следующему (traceback
вывод):В этот момент вы можете выбрать, в какой «фрейм» войти. Когда вы сделаете выбор, вы перейдете в
browser()
режим:И вы можете исследовать среду, которая была во время ошибки. Когда вы закончите, введите
c
текст, чтобы вернуться в меню выбора кадра. Когда вы закончите, как он говорит вам, введите,0
чтобы выйти.источник
Я дал этот ответ на более свежий вопрос, но добавляю его здесь для полноты картины.
Лично я не использую функции для отладки. Я часто обнаруживаю, что это доставляет столько же проблем, сколько и решает. Кроме того, исходя из опыта работы с Matlab, мне нравится делать это в интегрированной среде разработки (IDE), а не в коде. Использование IDE делает ваш код чистым и простым.
Для R я использую среду IDE под названием «RStudio» ( http://www.rstudio.com ), которая доступна для Windows, Mac и Linux и довольно проста в использовании.
Версии Rstudio, выпущенные примерно с октября 2013 года (0.98ish?), Имеют возможность добавлять точки останова в сценарии и функции: для этого просто щелкните левое поле файла, чтобы добавить точку останова. Вы можете установить точку останова, а затем перейти к ней. У вас также есть доступ ко всем данным в этой среде, поэтому вы можете опробовать команды.
Подробнее см. Http://www.rstudio.com/ide/docs/debugging/overview . Если у вас уже установлен Rstudio, вам может потребоваться обновление - это относительно новая функция (конец 2013 года).
Вы также можете найти другие IDE с аналогичной функциональностью.
По общему признанию, если это встроенная функция, вам, возможно, придется прибегнуть к некоторым предложениям, сделанным другими людьми в этом обсуждении. Но если это ваш собственный код, который требует исправления, решение на основе IDE может быть именно тем, что вам нужно.
источник
Отладка методов ссылочного класса без ссылки на экземпляр
источник
Я начинаю думать, что не печатать номер строки ошибки - самое основное требование - ПО УМОЛЧАНИЮ - это какая-то шутка в R / Rstudio . Единственный надежный метод, который я нашел, чтобы определить, где произошла ошибка, - это приложить дополнительные усилия для вызова функции traceback () и увидеть верхнюю строку.
источник