R 调试的一般建议

发布于 2024-10-07 17:58:09 字数 468 浏览 0 评论 0 原文

使用我编写的 R 函数时出现错误:

Warning messages:
1: glm.fit: algorithm did not converge 
2: glm.fit: algorithm did not converge 

我所做的:

  1. 逐步执行该函数
  2. 添加 print 以找出错误发生在哪一行建议两个不应使用 的函数glm.fit。它们是window()save()

我的一般方法包括添加 printstop 命令,并逐行单步执行函数,直到找到异常。

但是,我不清楚使用这些技术时代码中的错误来自何处。我什至不确定代码中的哪些函数依赖于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:

  1. Step through the function
  2. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

幸福丶如此 2024-10-14 17:58:27

我开始认为不打印错误行号 - 最基本的要求 - 默认 - 是 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.

一绘本一梦想 2024-10-14 17:58:26

在没有实例引用的情况下调试引用类方法

ClassName$trace(methodName, browser)

To debug Reference Class methods without instance reference

ClassName$trace(methodName, browser)
暖阳 2024-10-14 17:58:25

我对最近的问题给出了这个答案,,但为了完整起见,我将其添加到此处。

我个人倾向于不使用函数来调试。我经常发现这带来的麻烦和解决的麻烦一样多。另外,由于有 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 详细信息。如果您已经安装了 Rstudio,则可能需要升级 - 这是一个相对较新的(2013 年末)功能。

您可能还会发现其他具有类似功能的 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.

沉鱼一梦 2024-10-14 17:58:24

我喜欢加文的回答:我不知道选项(错误=恢复)。我还喜欢使用“调试”包,它提供了一种直观的方式来逐步执行代码。

require(debug)
mtrace(foo)
foo(1)

此时,它会打开一个单独的调试窗口,显示您的函数,并用黄线显示您在代码中的位置。在主窗口中,代码进入调试模式,您可以继续按 Enter 键来单步执行代码(还有其他命令),并检查变量值等。调试窗口中的黄线不断移动以显示位置你在代码中。完成调试后,您可以使用以下命令关闭跟踪:

mtrace.off()

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.

require(debug)
mtrace(foo)
foo(1)

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:

mtrace.off()
暮年 2024-10-14 17:58:24

根据我在此处收到的答案,您一定应该查看选项(error=recover) 设置。设置此选项后,遇到错误时,您将在控制台上看到类似于以下内容的文本(traceback 输出):

> source(<my filename>)
Error in plot.window(...) : need finite 'xlim' values
In addition: Warning messages:
1: In xy.coords(x, y, xlabel, ylabel, log) : NAs introduced by coercion
2: In min(x) : no non-missing arguments to min; returning Inf
3: In max(x) : no non-missing arguments to max; returning -Inf

Enter a frame number, or 0 to exit   

1: source(<my filename>)
2: eval.with.vis(ei, envir)
3: eval.with.vis(expr, envir, enclos)
4: LinearParamSearch(data = dataset, y = data.frame(LGD = dataset$LGD10), data.names = data
5: LinearParamSearch.R#66: plot(x = x, y = y.data, xlab = names(y), ylab = data.names[i])
6: LinearParamSearch.R#66: plot.default(x = x, y = y.data, xlab = names(y), ylab = data.nam
7: LinearParamSearch.R#66: localWindow(xlim, ylim, log, asp, ...)
8: LinearParamSearch.R#66: plot.window(...)

Selection:

此时您可以选择要输入的“帧”。当您做出选择时,您将进入 browser() 模式:

Selection: 4
Called from: stop(gettextf("replacement has %d rows, data has %d", N, n), 
    domain = NA)
Browse[1]> 

并且您可以检查发生错误时的环境。完成后,输入 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):

> source(<my filename>)
Error in plot.window(...) : need finite 'xlim' values
In addition: Warning messages:
1: In xy.coords(x, y, xlabel, ylabel, log) : NAs introduced by coercion
2: In min(x) : no non-missing arguments to min; returning Inf
3: In max(x) : no non-missing arguments to max; returning -Inf

Enter a frame number, or 0 to exit   

1: source(<my filename>)
2: eval.with.vis(ei, envir)
3: eval.with.vis(expr, envir, enclos)
4: LinearParamSearch(data = dataset, y = data.frame(LGD = dataset$LGD10), data.names = data
5: LinearParamSearch.R#66: plot(x = x, y = y.data, xlab = names(y), ylab = data.names[i])
6: LinearParamSearch.R#66: plot.default(x = x, y = y.data, xlab = names(y), ylab = data.nam
7: LinearParamSearch.R#66: localWindow(xlim, ylim, log, asp, ...)
8: LinearParamSearch.R#66: plot.window(...)

Selection:

At which point you can choose which "frame" to enter. When you make a selection, you'll be placed into browser() mode:

Selection: 4
Called from: stop(gettextf("replacement has %d rows, data has %d", N, n), 
    domain = NA)
Browse[1]> 

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, type 0 to exit.

空城之時有危險 2024-10-14 17:58:21

Mark Bravington 的调试器可以作为 CRAN 上的 debug 包使用,非常好而且非常简单。

library(debug);
mtrace(myfunction);
myfunction(a,b);
#... debugging, can query objects, step, skip, run, breakpoints etc..
qqq(); # quit the debugger only
mtrace.off(); # turn off debugging

代码会在突出显示的 Tk 窗口中弹出,以便您可以看到发生了什么,当然您可以在不同的函数中调用另一个 mtrace()

华泰

Mark Bravington's debugger which is available as the package debug on CRAN is very good and pretty straight forward.

library(debug);
mtrace(myfunction);
myfunction(a,b);
#... debugging, can query objects, step, skip, run, breakpoints etc..
qqq(); # quit the debugger only
mtrace.off(); # turn off debugging

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

我家小可爱 2024-10-14 17:58:20

在完成此处建议的所有步骤后,我刚刚了解到在 foreach() 中设置 .verbose = TRUE 也为我提供了大量有用的信息。特别是,foreach(.verbose=TRUE) 准确显示了 foreach 循环内发生错误的位置,而 traceback() 则不查看 foreach 循环内部。

After going through all the steps suggested here I just learned that setting .verbose = TRUE in foreach() also gives me tons of useful information. In particular foreach(.verbose=TRUE) shows exactly where an error occurs inside the foreach loop, while traceback() does not look inside the foreach loop.

九公里浅绿 2024-10-14 17:58:19

我的一般策略如下所示:

  1. 运行 traceback() 以查看是否存在明显问题
  2. 设置 options(warn=2) 以处理类似错误的警告
  3. Set options(error= recovery) 在出错时进入调用堆栈

My general strategy looks like:

  1. Run traceback() to see look for obvious issues
  2. Set options(warn=2) to treat warnings like errors
  3. Set options(error=recover) to step into the call stack on error
祁梦 2024-10-14 17:58:18

因此,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() and debug() walk into a bar, but trace() 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 using undebug (that is, after debug(foo), running the function foo will enter "debug" mode every time until you run undebug(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 example browser. This is useful for functions from packages and you're too lazy to get the nicely folded source code.

傻比既视感 2024-10-14 17:58:17

在某个时刻,glm.fit 被调用。这意味着您调用的函数之一或这些函数调用的函数之一正在使用 glmglm.fit

另外,正如我在上面的评论中提到的,这是一个警告而不是错误,这有很大的不同。您无法从警告中触发任何 R 调试工具(在有人告诉我我错了之前使用默认选项;-)。

如果我们更改选项以将警告转变为错误,那么我们就可以开始使用 R 的调试工具。从 ?options 我们有:

 ‘warn’: sets the handling of warning messages.  If ‘warn’ is
      negative all warnings are ignored.  If ‘warn’ is zero (the
      default) warnings are stored until the top-level function
      returns.  If fewer than 10 warnings were signalled they will
      be printed otherwise a message saying how many (max 50) were
      signalled.  An object called ‘last.warning’ is created and
      can be printed through the function ‘warnings’.  If ‘warn’ is
      one, warnings are printed as they occur.  If ‘warn’ is two or
      larger all warnings are turned into errors.

因此,如果您运行

options(warn = 2)

然后运行您的代码,R 将抛出错误。此时,您可以运行

traceback()

查看调用堆栈。这是一个例子。

> options(warn = 2)
> foo <- function(x) bar(x + 2)
> bar <- function(y) warning("don't want to use 'y'!")
> foo(1)
Error in bar(x + 2) : (converted from warning) don't want to use 'y'!
> traceback()
7: doWithOneRestart(return(expr), restart)
6: withOneRestart(expr, restarts[[1L]])
5: withRestarts({
       .Internal(.signalCondition(simpleWarning(msg, call), msg, 
           call))
       .Internal(.dfltWarn(msg, call))
   }, muffleWarning = function() NULL)
4: .signalSimpleWarning("don't want to use 'y'!", quote(bar(x + 
       2)))
3: warning("don't want to use 'y'!")
2: bar(x + 2)
1: foo(1)

在这里您可以忽略标记为 4: 及更高版本的帧。我们看到 foo 调用了 bar 并且 bar 生成了警告。这应该会显示哪些函数正在调用 glm.fit

如果你现在想调试这个,我们可以转向另一个选项,告诉 R 在遇到错误时进入调试器,并且由于我们已经发出了警告错误,所以当触发原始警告时,我们将得到一个调试器。为此,您应该运行:

options(error = recover)

这是一个示例:

> options(error = recover)
> foo(1)
Error in bar(x + 2) : (converted from warning) don't want to use 'y'!

Enter a frame number, or 0 to exit   

1: foo(1)
2: bar(x + 2)
3: warning("don't want to use 'y'!")
4: .signalSimpleWarning("don't want to use 'y'!", quote(bar(x + 2)))
5: withRestarts({
6: withOneRestart(expr, restarts[[1]])
7: doWithOneRestart(return(expr), restart)

Selection:

然后您可以进入任何这些帧以查看引发警告时发生的情况。

要将上述选项重置为默认值,请输入

options(error = NULL, warn = 0)

至于您引用的特定警告,您很可能需要允许代码中进行更多迭代。一旦您找到了调用 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 either glm, 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:

 ‘warn’: sets the handling of warning messages.  If ‘warn’ is
      negative all warnings are ignored.  If ‘warn’ is zero (the
      default) warnings are stored until the top-level function
      returns.  If fewer than 10 warnings were signalled they will
      be printed otherwise a message saying how many (max 50) were
      signalled.  An object called ‘last.warning’ is created and
      can be printed through the function ‘warnings’.  If ‘warn’ is
      one, warnings are printed as they occur.  If ‘warn’ is two or
      larger all warnings are turned into errors.

So if you run

options(warn = 2)

then run your code, R will throw an error. At which point, you could run

traceback()

to see the call stack. Here is an example.

> options(warn = 2)
> foo <- function(x) bar(x + 2)
> bar <- function(y) warning("don't want to use 'y'!")
> foo(1)
Error in bar(x + 2) : (converted from warning) don't want to use 'y'!
> traceback()
7: doWithOneRestart(return(expr), restart)
6: withOneRestart(expr, restarts[[1L]])
5: withRestarts({
       .Internal(.signalCondition(simpleWarning(msg, call), msg, 
           call))
       .Internal(.dfltWarn(msg, call))
   }, muffleWarning = function() NULL)
4: .signalSimpleWarning("don't want to use 'y'!", quote(bar(x + 
       2)))
3: warning("don't want to use 'y'!")
2: bar(x + 2)
1: foo(1)

Here you can ignore the frames marked 4: and higher. We see that foo called bar and that bar generated the warning. That should show you which functions were calling glm.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:

options(error = recover)

Here is an example:

> options(error = recover)
> foo(1)
Error in bar(x + 2) : (converted from warning) don't want to use 'y'!

Enter a frame number, or 0 to exit   

1: foo(1)
2: bar(x + 2)
3: warning("don't want to use 'y'!")
4: .signalSimpleWarning("don't want to use 'y'!", quote(bar(x + 2)))
5: withRestarts({
6: withOneRestart(expr, restarts[[1]])
7: doWithOneRestart(return(expr), restart)

Selection:

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

options(error = NULL, warn = 0)

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 the control argument using glm.control - see ?glm.control.

空心空情空意 2024-10-14 17:58:16

正如在另一个问题、Rprof()summaryRprof()找到程序中缓慢的部分,这些部分可能会因加速或转向 C/C++ 实现而受益。如果您正在进行模拟工作或其他计算或数据密集型活动,这可能更适用。 profr可以帮助可视化结果。

我正在学习调试,所以来自 另一个线程的另一个建议< /a>:

  • 设置 options(warn=2) 将警告视为错误

您还可以使用 options 在出现错误或警告时立即采取行动发生时,使用您最喜欢的调试功能。例如:

  • 设置 options(error=recover) 以在发生错误时运行 recover(),正如 Shane 指出的那样(以及 R 调试指南。或者您认为运行有用的任何其他方便的功能以及

@Shane 的 链接 之一中的另外两个方法:

  • 使用 try() 返回有关
  • *apply 函数的更多信息,请使用 .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 中提供了新函数:

  • findLineNum() 获取源文件名和行号并返回函数和环境。当您 source() 一个 .R 文件并且它在第 #n 行返回错误时,这似乎很有帮助,但您需要知道第 #n 行位于什么函数。
  • setBreakpoint() 获取源文件名和行号,并在其中设置断点

codetools 包,特别是它的 checkUsage 函数对于快速获取编译器通常报告的语法和风格错误(未使用的局部变量、未定义的全局变量)特别有帮助。函数和变量、部分参数匹配等等)。

setBreakpoint()trace() 的更用户友好的前端。有关其工作原理的内部细节,请参阅最近的 R 期刊文章

如果您尝试调试其他人的包,一旦找到问题,您可以 使用 fixInNamespaceassignInNamespace 覆盖它们的函数,但不要在生产代码中使用它。

所有这些都不应妨碍久经考验的标准 R 调试工具,其中一些在上面,另一些则不在。特别是,事后调试工具非常方便当您有一堆耗时的代码而您不想重新运行时。

最后,对于似乎不会引发错误消息的棘手问题,您可以使用 options(error=dump.frames) ,如本问题所述:
没有抛出错误的错误

As was pointed out to me in another question, Rprof() and summaryRprof() 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. The profr package can help visualizing the results.

I'm on a bit of a learn-about-debugging kick, so another suggestion from another thread:

  • Set options(warn=2) to treat warnings like errors

You 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:

  • Set options(error=recover) to run recover() 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:

  • Wrap an inner function call with try() to return more information on it.
  • For *apply functions, use .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:

  • Put inside the function you might want to debug browser(expr=isTRUE(getOption("myDebug")))
  • And set the global option by options(myDebug=TRUE)
  • You could even wrap the browser call: myBrowse <- browser(expr=isTRUE(getOption("myDebug"))) and then call with myBrowse() 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 you source() 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 there

The 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 to trace(). 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 and assignInNamespace, 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

家住魔仙堡 2024-10-14 17:58:15

到目前为止我见过的最好的演练是:

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?

栀子花开つ 2024-10-14 17:58:13

我想说调试是一种艺术形式,所以没有明确的灵丹妙药。任何语言都有很好的调试策略,它们也适用于这里(例如 阅读这篇好文章)。例如,第一件事是重现问题...如果您做不到这一点,那么您需要获取更多信息(例如通过日志记录)。一旦您可以重现它,您需要将其减少到源代码。

我想说的是,我有一个最喜欢的调试例程,而不是“技巧”:

  1. 发生错误时,我通常做的第一件事是通过调用 traceback() 查看堆栈跟踪:显示错误发生的位置,如果您有多个嵌套函数,这尤其有用。
  2. 接下来我将设置 options(error=recover);这会立即切换到发生错误的浏览器模式,以便您可以从那里浏览工作区。
  3. 如果我仍然没有足够的信息,我通常使用 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:

  1. When an error occurs, the first thing that I usually do is look at the stack trace by calling traceback(): that shows you where the error occurred, which is especially useful if you have several nested functions.
  2. Next I will set options(error=recover); this immediately switches into browser mode where the error occurs, so you can browse the workspace from there.
  3. If I still don't have enough information, I usually use the 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() and setBreakpoint() functions.

As a final comment: depending upon the error, it is also very helpful to set try() or tryCatch() 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:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文