使用我编写的 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。 我该如何诊断这个问题?
I get an error when using an R function that I wrote:
Warning messages:
1: glm.fit: algorithm did not converge
2: glm.fit: algorithm did not converge
What I have done:
- Step through the function
- Adding print to find out at what line the error occurs suggests two functions that should not use
glm.fit
. They are window()
and save()
.
My general approaches include adding print
and stop
commands, and stepping through a function line by line until I can locate the exception.
However, it is not clear to me using those techniques where this error comes from in the code. I am not even certain which functions within the code depend on glm.fit
. How do I go about diagnosing this problem?
发布评论
评论(13)
我想说调试是一种艺术形式,所以没有明确的灵丹妙药。 任何语言都有很好的调试策略,它们也适用于这里(例如 阅读这篇好文章)。 例如,第一件事是重现问题...如果您做不到这一点,那么您需要获取更多信息(例如通过日志记录)。 一旦您可以重现它,您需要将其减少到源代码。
我想说的是,我有一个最喜欢的调试例程,而不是“技巧”:
traceback()
查看堆栈跟踪:显示错误发生的位置,如果您有多个嵌套函数,这尤其有用。options(error=recover)
; 这会立即切换到发生错误的浏览器模式,以便您可以从那里浏览工作区。debug()
函数并逐行单步执行脚本。R 2.10 中最好的新技巧(使用脚本文件时)是使用
findLineNum()
和setBreakpoint()
函数。最后的评论:根据错误,围绕外部函数调用设置 try() 或 tryCatch() 语句也非常有帮助(特别是在处理 S4 类时) )。 这有时会提供更多信息,并且还可以让您更好地控制运行时如何处理错误。
这些相关问题有很多建议:
I'd say that debugging is an art form, so there's no clear silver bullet. There are good strategies for debugging in any language, and they apply here too (e.g. read this nice article). For instance, the first thing is to reproduce the problem...if you can't do that, then you need to get more information (e.g. with logging). Once you can reproduce it, you need to reduce it down to the source.
Rather than a "trick", I would say that I have a favorite debugging routine:
traceback()
: that shows you where the error occurred, which is especially useful if you have several nested functions.options(error=recover)
; this immediately switches into browser mode where the error occurs, so you can browse the workspace from there.debug()
function and step through the script line by line.The best new trick in R 2.10 (when working with script files) is to use the
findLineNum()
andsetBreakpoint()
functions.As a final comment: depending upon the error, it is also very helpful to set
try()
ortryCatch()
statements around external function calls (especially when dealing with S4 classes). That will sometimes provide even more information, and it also gives you more control over how errors are handled at run time.These related questions have a lot of suggestions:
到目前为止我见过的最好的演练是:
http:// /www.biostat.jhsph.edu/%7Erpeng/docs/R-debug-tools.pdf
有人同意/不同意吗?
The best walkthrough I've seen so far is:
http://www.biostat.jhsph.edu/%7Erpeng/docs/R-debug-tools.pdf
Anybody agree/disagree?
正如在另一个问题、
Rprof()
和summaryRprof()
是 找到程序中缓慢的部分,这些部分可能会因加速或转向 C/C++ 实现而受益。 如果您正在进行模拟工作或其他计算或数据密集型活动,这可能更适用。profr
包可以帮助可视化结果。我正在学习调试,所以来自 另一个线程的另一个建议< /a>:
options(warn=2)
将警告视为错误您还可以使用
options
在出现错误或警告时立即采取行动发生时,使用您最喜欢的调试功能。 例如:options(error=recover)
以在发生错误时运行recover()
,正如 Shane 指出的那样(以及 R 调试指南。或者您认为运行有用的任何其他方便的功能以及@Shane 的链接之一中的另外两个方法:
try()
返回有关.inform=TRUE
(来自 plyr 包)作为 apply 命令的选项@JoshuaUlrich 还指出一种使用经典
browser()< 的条件功能的巧妙方法/code> 打开/关闭调试的命令:
browser(expr=isTRUE(getOption("myDebug")))
设置全局选项options(myDebug=TRUE)
myBrowse <- browser(expr=isTRUE(getOption("myDebug")))
然后使用调用myBrowse()
因为它使用全局变量。R 2.10 中提供了新函数:
source()
一个 .R 文件并且它在第 #n 行返回错误时,这似乎很有帮助,但您需要知道第 #n 行位于什么函数。setBreakpoint()
获取源文件名和行号,并在其中设置断点codetools 包,特别是它的
checkUsage
函数对于快速获取编译器通常报告的语法和风格错误(未使用的局部变量、未定义的全局变量)特别有帮助。函数和变量、部分参数匹配等等)。setBreakpoint()
是trace()
的更用户友好的前端。 有关其工作原理的内部细节,请参阅最近的 R 期刊文章。如果您尝试调试其他人的包,一旦找到问题,您可以 使用
fixInNamespace
和assignInNamespace
覆盖它们的函数,但不要在生产代码中使用它。所有这些都不应妨碍久经考验的标准 R 调试工具,其中一些在上面,另一些则不在。 特别是,事后调试工具非常方便当您有一堆耗时的代码而您不想重新运行时。
最后,对于似乎不会引发错误消息的棘手问题,您可以使用
options(error=dump.frames)
,如本问题所述:没有抛出错误的错误
As was pointed out to me in another question,
Rprof()
andsummaryRprof()
are nice tools to find slow parts of your program that might benefit from speeding up or moving to a C/C++ implementation. This probably applies more if you're doing simulation work or other compute- or data-intensive activities. Theprofr
package can help visualizing the results.I'm on a bit of a learn-about-debugging kick, so another suggestion from another thread:
options(warn=2)
to treat warnings like errorsYou can also use
options
to drop you right into the heat of the action when an error or warning occurs, using your favorite debugging function of choice. For instance:options(error=recover)
to runrecover()
when an error occurs, as Shane noted (and as is documented in the R debugging guide. Or any other handy function you would find useful to have run.And another two methods from one of @Shane's links:
try()
to return more information on it..inform=TRUE
(from the plyr package) as an option to the apply command@JoshuaUlrich also pointed out a neat way of using the conditional abilities of the classic
browser()
command to turn on/off debugging:browser(expr=isTRUE(getOption("myDebug")))
options(myDebug=TRUE)
myBrowse <- browser(expr=isTRUE(getOption("myDebug")))
and then call withmyBrowse()
since it uses globals.Then there are the new functions available in R 2.10:
findLineNum()
takes a source file name and line number and returns the function and environment. This seems to be helpful when yousource()
a .R file and it returns an error at line #n, but you need to know what function is located at line #n.setBreakpoint()
takes a source file name and line number and sets a breakpoint thereThe codetools package, and particularly its
checkUsage
function can be particularly helpful in quickly picking up syntax and stylistic errors that a compiler would typically report (unused locals, undefined global functions and variables, partial argument matching, and so forth).setBreakpoint()
is a more user-friendly front-end totrace()
. Details on the internals of how this works are available in a recent R Journal article.If you are trying to debug someone else's package, once you have located the problem you can over-write their functions with
fixInNamespace
andassignInNamespace
, but do not use this in production code.None of this should preclude the tried-and-true standard R debugging tools, some of which are above and others of which are not. In particular, the post-mortem debugging tools are handy when you have a time-consuming bunch of code that you'd rather not re-run.
Finally, for tricky problems which don't seem to throw an error message, you can use
options(error=dump.frames)
as detailed in this question:Error without an error being thrown
在某个时刻,
glm.fit
被调用。 这意味着您调用的函数之一或这些函数调用的函数之一正在使用glm
、glm.fit
。另外,正如我在上面的评论中提到的,这是一个警告而不是错误,这有很大的不同。 您无法从警告中触发任何 R 调试工具(在有人告诉我我错了之前使用默认选项;-)。
如果我们更改选项以将警告转变为错误,那么我们就可以开始使用 R 的调试工具。 从
?options
我们有:因此,如果您运行
然后运行您的代码,R 将抛出错误。 此时,您可以运行
查看调用堆栈。 这是一个例子。
在这里您可以忽略标记为
4:
及更高版本的帧。 我们看到foo
调用了bar
并且bar
生成了警告。 这应该会显示哪些函数正在调用glm.fit
。如果你现在想调试这个,我们可以转向另一个选项,告诉 R 在遇到错误时进入调试器,并且由于我们已经发出了警告错误,所以当触发原始警告时,我们将得到一个调试器。 为此,您应该运行:
这是一个示例:
然后您可以进入任何这些框架以查看抛出警告时发生的情况。
要将上述选项重置为默认值,请输入
至于您引用的特定警告,您很可能需要允许代码中进行更多迭代。 一旦您找到了调用
glm.fit
的内容,就可以了解如何使用glm.control
向其传递control
参数 - 请参阅 <代码>?glm.control。At some point,
glm.fit
is being called. That means one of the functions you call or one of the functions called by those functions is using eitherglm
,glm.fit
.Also, as I mention in my comment above, that is a warning not an error, which makes a big difference. You can't trigger any of R's debugging tools from a warning (with default options before someone tells me I am wrong ;-).
If we change the options to turn warnings into errors then we can start to use R's debugging tools. From
?options
we have:So if you run
then run your code, R will throw an error. At which point, you could run
to see the call stack. Here is an example.
Here you can ignore the frames marked
4:
and higher. We see thatfoo
calledbar
and thatbar
generated the warning. That should show you which functions were callingglm.fit
.If you now want to debug this, we can turn to another option to tell R to enter the debugger when it encounters an error, and as we have made warnings errors we will get a debugger when the original warning is triggered. For that you should run:
Here is an example:
You can then step into any of those frames to see what was happening when the warning was thrown.
To reset the above options to their default, enter
As for the specific warning you quote, it is highly likely that you need to allow more iterations in the code. Once you've found out what is calling
glm.fit
, work out how to pass it thecontrol
argument usingglm.control
- see?glm.control
.因此,
browser()
、traceback()
和debug()
走进酒吧,但trace()
等待外部并保持电机运转。通过在函数中的某处插入
browser
,执行将停止并等待您的输入。 您可以使用 n (或 Enter)前进,使用 c 运行整个块(迭代),使用 < 完成当前循环/函数kbd>f,或使用 Q 退出; 请参阅?浏览器
。使用
debug
,您可以获得与浏览器相同的效果,但这会在函数开始时停止执行。 相同的快捷方式也适用。 该函数将处于“调试”模式,直到您使用undebug
将其关闭(即在debug(foo)
之后,运行函数foo 每次都会进入“调试”模式,直到运行
undebug(foo)
)。一个更短暂的替代方案是debugonce,它将在下次评估函数后从函数中删除“调试”模式。
traceback
将为您提供函数的执行流程,直到出现问题的地方(实际错误)。您可以使用
trace
在函数中插入代码位(即自定义函数),例如browser
。 这对于包中的函数很有用,而您却懒得获得折叠良好的源代码。So
browser()
,traceback()
anddebug()
walk into a bar, buttrace()
waits outside and keeps the motor running.By inserting
browser
somewhere in your function, the execution will halt and wait for your input. You can move forward using n (or Enter), run the entire chunk (iteration) with c, finish the current loop/function with f, or quit with Q; see?browser
.With
debug
, you get the same effect as with browser, but this stops the execution of a function at its beginning. Same shortcuts apply. This function will be in a "debug" mode until you turn it off usingundebug
(that is, afterdebug(foo)
, running the functionfoo
will enter "debug" mode every time until you runundebug(foo)
).A more transient alternative is
debugonce
, which will remove the "debug" mode from the function after the next time it's evaluated.traceback
will give you the flow of execution of functions all the way up to where something went wrong (an actual error).You can insert code bits (i.e. custom functions) in functions using
trace
, for examplebrowser
. This is useful for functions from packages and you're too lazy to get the nicely folded source code.我的一般策略如下所示:
traceback()
以查看是否存在明显问题options(warn=2)
以处理类似错误的警告options(error= recovery)
在出错时进入调用堆栈My general strategy looks like:
traceback()
to see look for obvious issuesoptions(warn=2)
to treat warnings like errorsoptions(error=recover)
to step into the call stack on error在完成此处建议的所有步骤后,我刚刚了解到在
foreach()
中设置.verbose = TRUE
也为我提供了大量有用的信息。 特别是,foreach(.verbose=TRUE)
准确显示了 foreach 循环内发生错误的位置,而traceback()
则不查看 foreach 循环内部。After going through all the steps suggested here I just learned that setting
.verbose = TRUE
inforeach()
also gives me tons of useful information. In particularforeach(.verbose=TRUE)
shows exactly where an error occurs inside the foreach loop, whiletraceback()
does not look inside the foreach loop.Mark Bravington 的调试器可以作为 CRAN 上的
debug
包使用,非常好而且非常简单。代码会在突出显示的 Tk 窗口中弹出,以便您可以看到发生了什么,当然您可以在不同的函数中调用另一个
mtrace()
。华泰
Mark Bravington's debugger which is available as the package
debug
on CRAN is very good and pretty straight forward.The code pops up in a highlighted Tk window so you can see what's going on and, of course you can call another
mtrace()
while in a different function.HTH
我喜欢加文的回答:我不知道选项(错误=恢复)。 我还喜欢使用“调试”包,它提供了一种直观的方式来逐步执行代码。
此时,它会打开一个单独的调试窗口,显示您的函数,并用黄线显示您在代码中的位置。 在主窗口中,代码进入调试模式,您可以继续按 Enter 键来单步执行代码(还有其他命令),并检查变量值等。调试窗口中的黄线不断移动以显示位置你在代码中。 完成调试后,您可以使用以下命令关闭跟踪:
I like Gavin's answer: I did not know about options(error = recover). I also like to use the 'debug' package that gives a visual way to step through your code.
At this point it opens up a separate debug window showing your function, with a yellow line showing where you are in the code. In the main window the code enters debug mode, and you can keep hitting enter to step through the code (and there are other commands as well), and examine variable values, etc. The yellow line in the debug window keeps moving to show where you are in the code. When done with debugging, you can turn off tracing with:
根据我在此处收到的答案,您一定应该查看
选项(error=recover)
设置。 设置此选项后,遇到错误时,您将在控制台上看到类似于以下内容的文本(traceback
输出):此时您可以选择要输入的“框架”。 当您做出选择时,您将进入
browser()
模式:并且您可以检查发生错误时的环境。 完成后,输入
c
返回帧选择菜单。 当您完成后,正如它告诉您的那样,输入0
退出。Based on the answer I received here, you should definitely check out the
options(error=recover)
setting. When this is set, upon encountering an error, you'll see text on the console similar to the following (traceback
output):At which point you can choose which "frame" to enter. When you make a selection, you'll be placed into
browser()
mode:And you can examine the environment as it was at the time of the error. When you're done, type
c
to bring you back to the frame selection menu. When you're done, as it tells you, type0
to exit.我对最近的问题给出了这个答案,,但为了完整起见,我将其添加到此处。
我个人倾向于不使用函数来调试。 我经常发现这带来的麻烦和解决的麻烦一样多。 另外,由于有 Matlab 背景,我喜欢能够在集成开发环境 (IDE) 中完成此操作,而不是在代码中完成此操作。 使用 IDE 可以使您的代码保持干净、简单。
对于 R,我使用名为“RStudio”的 IDE (http://www.rstudio.com),它适用于 Windows、Mac 和 Linux,并且非常易于使用。
自 2013 年 10 月左右开始的 Rstudio 版本(0.98 左右?)能够在脚本和函数中添加断点:为此,只需单击文件的左边距即可添加断点。 您可以设置一个断点,然后从该点开始单步执行。 您还可以访问该环境中的所有数据,因此可以尝试命令。
请参阅http://www.rstudio.com/ide/docs/debugging/overview
您可能还会发现其他具有类似功能的 IDE。
诚然,如果它是内置函数,您可能必须求助于其他人在本次讨论中提出的一些建议。 但是,如果需要修复的是您自己的代码,那么基于 IDE 的解决方案可能正是您所需要的。
I gave this answer to a more recent question, but am adding it here for completeness.
Personally I tend not to use functions to debug. I often find that this causes as much trouble as it solves. Also, coming from a Matlab background I like being able to do this in an integrated development environment (IDE) rather than doing this in the code. Using an IDE keeps your code clean and simple.
For R, I use an IDE called "RStudio" (http://www.rstudio.com), which is available for windows, mac, and linux and is pretty easy to use.
Versions of Rstudio since about October 2013 (0.98ish?) have the capability to add breakpoints in scripts and functions: to do this, just click on the left margin of the file to add a breakpoint. You can set a breakpoint and then step through from that point on. You also have access to all of the data in that environment, so you can try out commands.
See http://www.rstudio.com/ide/docs/debugging/overview for details. If you already have Rstudio installed, you may need to upgrade - this is a relatively new (late 2013) feature.
You may also find other IDEs that have similar functionality.
Admittedly, if it's a built-in function you may have to resort to some of the suggestions made by other people in this discussion. But, if it's your own code that needs fixing, an IDE-based solution might be just what you need.
在没有实例引用的情况下调试引用类方法
To debug Reference Class methods without instance reference
我开始认为不打印错误行号 - 最基本的要求 - 默认 - 是 R/Rstudio 中的某种笑话。 我发现找到错误发生位置的唯一可靠方法是额外调用 traceback() 并查看顶行。
I am beginning to think that not printing error line number - a most basic requirement - BY DEFAILT- is some kind of a joke in R/Rstudio. The only reliable method I have found to find where an error occurred is to make the additional effort of calloing traceback() and see the top line.