Mar*_*ark 46 debugging unit-testing development-environment r
有哪些具体实用程序可以帮助R开发人员更有效地编码和调试?
我正在寻求建立一个R开发环境,并希望概述一些对我来说有用的工具,包括代码覆盖,调试,包文件和帮助文件的生成以及可能的UML建模.
注意:根据您对推荐工具的使用经验,请根据原因和示例证明您的答案.不要只是链接.
had*_*ley 50
我写了太多的软件包,所以为了保持可管理性,我在基础架构软件包上投入了大量时间:帮助我使代码更加健壮并帮助其他人更轻松地使用的软件包.这些包括:
roxygen2
(使用Manuel Eugster和Peter Danenberg),它允许您将文档保存在它所记录的函数旁边,这使得我更有可能保持它的最新状态.roxygen2
还有一些新功能,旨在最大限度地减少文档重复:templates(@template
),参数继承(@inheritParams
)和函数系列(@family
)等等.
testthat
自动化我的代码测试.这变得越来越重要,因为我的代码编写时间越来越少:自动化测试记住函数应该如何工作,即使我不这样做.
devtools
自动执行许多常见的开发任务(正如Andrie所说).最终的目标devtools
是让它像R CMD check
在后台持续运行一样,并通知您实例出错.
profr
,特别是未发布的交互式浏览器,使我很容易在我的代码中找到瓶颈.
helpr
(与Barret Schloerke合作),即将推出http://had.co.nz/ggplot2,为R文档提供了一个优雅的html界面.
有用的R功能:
apropos
:我总是忘记有用函数的名称,并apropos
帮助我找到它们,即使我只记得一个片段R之外:
我使用textmate编辑R(和其他)文件,但我不认为它真的那么重要.选择一个并了解它的所有角落和缝隙.
花一些时间学习命令行.从长远来看,您可以做的任何事情都可以使工作流程的任何部分自动化.从命令行运行R会导致一个自然过程,每个项目都有自己的R实例; 我经常一次运行2-5个R实例.
使用版本控制.我喜欢git
和github.同样,您使用哪个系统并不重要,但掌握它!
我希望R拥有的东西:
Dir*_*tel 46
我记得以前曾经问过,我的答案仍然是一样的:Emacs.
Emacs可以
M-x shell
和/或M-x eshell
具有带有直接模式的良好目录访问功能运行shell ,具有用于远程访问的ssh模式<tongueInCheek>
不是Eclipse,不需要Java</tongueInCheek>
您当然可以将它与您喜欢的任何CRAN包组合:RUnit或testthat,不同的配置文件支持包,调试包,......
其他有用的工具:
R CMD check
真的是你的朋友,因为这是CRAN用来决定你是"进出"的东西; 使用它并信任它tests/
目录可以提供单元测试的简化版本,通过保存待比较输出(来自之前的R CMD check
运行),这是有用的,但适当的单元测试更好r -lfoo -e'bar(1, "ab")'
启动R会话,加载foo
包并评估给定的表达式(这里是一个bar()
带有两个参数的函数).与此相结合R CMD INSTALL
,提供了完整的测试周期.对基本R调试工具的了解和使用能力是学习快速调试R代码的关键第一步.如果您知道如何使用基本工具,则可以在任何地方调试代码,而无需使用附加软件包中提供的所有额外工具.
traceback()
允许您查看导致错误的调用堆栈
foo <- function(x) {
d <- bar(x)
x[1]
}
bar <- function(x) {
stopifnot(is.matrix(x))
dim(x)
}
foo(1:10)
traceback()
Run Code Online (Sandbox Code Playgroud)
收益率:
> foo(1:10)
Error: is.matrix(x) is not TRUE
> traceback()
4: stop(paste(ch, " is not ", if (length(r) > 1L) "all ", "TRUE",
sep = ""), call. = FALSE)
3: stopifnot(is.matrix(x))
2: bar(x)
1: foo(1:10)
Run Code Online (Sandbox Code Playgroud)
所以我们可以清楚地看到错误发生在功能上bar()
; 我们缩小了寻找bug的范围.但是如果代码生成警告而不是错误呢?这可以通过以下warn
选项将警告变为错误来处理:
options(warn = 2)
Run Code Online (Sandbox Code Playgroud)
会将警告变成错误.然后,您可以使用它traceback()
来追踪它们.
与此相关联的是让R从代码中的错误中恢复,以便您可以调试出错的地方.options(error = recover)
每当出现错误时,我们都会将我们放入调试器框架中:
> options(error = recover)
> foo(1:10)
Error: is.matrix(x) is not TRUE
Enter a frame number, or 0 to exit
1: foo(1:10)
2: bar(x)
3: stopifnot(is.matrix(x))
Selection: 2
Called from: bar(x)
Browse[1]> x
[1] 1 2 3 4 5 6 7 8 9 10
Browse[1]> is.matrix(x)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)
你看,我们可以进入调用堆栈的每一帧,看看函数是如何被调用的,参数是什么等等.在上面的例子中,我们看到bar()
传递了一个向量而不是一个矩阵,因此出现了错误.options(error = NULL)
将此行为重置为正常.
另一个关键功能是trace()
,它允许您将调试调用插入现有函数.这样做的好处是你可以让R从源代码中的特定行调试:
> x <- 1:10; y <- rnorm(10)
> trace(lm, tracer = browser, at = 10) ## debug from line 10 of the source
Tracing function "lm" in package "stats"
[1] "lm"
> lm(y ~ x)
Tracing lm(y ~ x) step 10
Called from: eval(expr, envir, enclos)
Browse[1]> n ## must press n <return> to get the next line step
debug: mf <- eval(mf, parent.frame())
Browse[2]>
debug: if (method == "model.frame") return(mf) else if (method != "qr") warning(gettextf("method = '%s' is not supported. Using 'qr'",
method), domain = NA)
Browse[2]>
debug: if (method != "qr") warning(gettextf("method = '%s' is not supported. Using 'qr'",
method), domain = NA)
Browse[2]>
debug: NULL
Browse[2]> Q
> untrace(lm)
Untracing function "lm" in package "stats"
Run Code Online (Sandbox Code Playgroud)
这允许您在代码中的正确位置插入调试调用,而无需单步执行前面的函数调用.
如果要在执行时逐步执行debug(foo)
函数foo()
,undebug(foo)
则会打开调试器以获取函数,同时将关闭调试器.
关于这些选项的一个关键点是我不需要修改/编辑任何源代码来插入调试调用等.我可以尝试一下,直接从发生错误的会话中查看问题所在.
有关R中的不同调试,请参阅Mark Bravington 在CRAN上的调试包
归档时间: |
|
查看次数: |
6044 次 |
最近记录: |