【问题标题】:What core packages should a professional R developer have, and why? [closed]专业的 R 开发人员应该拥有哪些核心包,为什么? [关闭]
【发布时间】:2011-10-11 09:48:27
【问题描述】:

可以帮助 R 开发人员更有效地编码和调试的具体实用程序有哪些?

我正在寻找建立一个 R 开发环境,并希望了解对我有用的工具的概述,这些工具对我制作具有代码覆盖率、调试、生成包文件和帮助文件的单元测试基础架构很有用,也许UML 建模。

注意:请根据您对推荐工具的使用经验,用理由和示例证明您的回答。 不要只是链接

相关

【问题讨论】:

  • 我有点惊讶没有人提到 RStudio (wwww.rstudio.org)
  • @Brandon :RStudio 很棒,但还不足以开发包。它肯定会到达那里,我喜欢他们到现在为止所做的事情。
  • 在再次投票结束此问题之前,请阅读meta.stackexchange.com/questions/100617 - 谢谢如果您想在讨论中发表意见,请将其提交给 meta。边缘问题所做的一件事是在 cmets 中产生噪音。我不会允许的。讨论元数据,而不是在这里。
  • 我已尝试将其编辑为特定的内容(“推荐所有我想要的工具”不是任何人都可以回答的问题)。我还关闭/合并了其他几个类似的问题,以尝试在此处创建一组有用的 r-tools 帖子。回答时请注意注意 - 如果这演变成不合理的链接和/或自我推销的列表,它将被关闭并毫不留情地删除 - 您的目标应该是帮助那些可以使用 Google,但需要专家建议来理解结果,而不仅仅是不断变化的工具环境的快照列表。

标签: unit-testing debugging r development-environment


【解决方案1】:

了解和使用基本的 R 调试工具是学习快速调试 R 代码必不可少的第一步。如果您知道如何使用基本工具,则可以在任何地方调试代码,而无需附加包中提供的所有额外工具。

traceback() 可以让你看到导致错误的调用堆栈

foo <- function(x) {
    d <- bar(x)
    x[1]
}
bar <- function(x) {
    stopifnot(is.matrix(x))
    dim(x)
}
foo(1:10)
traceback()

产量:

> 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)

所以我们可以清楚地看到错误发生在函数bar();我们缩小了寻找错误的范围。但是,如果代码生成警告而不是错误怎么办?这可以通过 warn 选项将警告变成错误来处理:

options(warn = 2)

会将警告变成错误。然后你可以使用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

您看到我们可以放入调用堆栈上的每一帧,看看函数是如何被调用的,参数是什么等等。在上面的例子中,我们看到 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"

这允许您在代码中的正确位置插入调试调用,而无需逐步执行正在进行的函数调用。

如果您想在函数执行时单步执行,那么debug(foo) 将为函数foo() 打开调试器,而undebug(foo) 将关闭调试器。

关于这些选项的一个关键点是,我不需要修改/编辑任何源代码来插入调试调用等。我可以尝试一下,直接从发生错误的会话中查看问题所在。

有关 R 中调试的不同看法,请参阅 Mark Bravington 在 CRAN 上的 debug

【讨论】:

    【解决方案2】:

    我记得以前有人问过这个问题,但我的回答还是一样:Emacs。

    Emacs 可以

    • 感谢ESS,用 R 做任何你想做的事情,包括
      • 各种sn-ps(行、区域、函数、缓冲区...)的代码执行
      • 检查工作区,
      • 变量的显示,
      • 多个 R 会话并在它们之间轻松切换
      • 用于重新运行(部分)以前会话的转录模式
      • 访问帮助系统
      • 还有更多
    • 通过 AucTex 模式轻松处理乳胶,这有助于 Sweave for R
    • 具有与 R 结合使用的任何其他编程语言的模式,无论是 C/C++、Python、shell、SQL 等等,涵盖自动缩进和颜色突出显示
    • 可以用sql-*模式访问数据库
    • 可以在tramp模式下远程工作:像访问本地文件一样访问远程文件(使用ssh/scp)
    • 可以作为守护进程运行,使其有状态,因此您可以重新连接到同一个 Emacs 会话,无论是在 X11(或同等设备)下的工作站上,还是通过 ssh(带或不带 X11)或屏幕远程连接。
    • org-mode,它与 babel 一起提供了一个强大的 sweave 替代方案,正如所讨论的 in this paper discussing workflow apps for (social) scientists
    • 可以通过M-x shell 和/或M-x eshell 运行shell,具有良好的目录访问功能和dired 模式,具有用于远程访问的ssh 模式
    • 通过特定模式轻松连接所有源代码存储库(例如 psvn for svn)
    • 与 R 一样是跨平台的,因此您可以在所有相关操作系统上获得相似的用户界面体验
    • 被广泛使用、广泛可用并且正在积极开发代码和扩展,请参阅 emacswiki.org 站点了解后者
    • &lt;tongueInCheek&gt;不是Eclipse,不需要Java&lt;/tongueInCheek&gt;

    您当然可以将它与您喜欢的任何 CRAN 包结合使用:RUnit 或 testthat、不同的分析支持包、调试包……

    其他有用的工具:

    • R CMD check 真的是你的朋友,因为这是 CRAN 用来决定你是“进还是出”的东西;使用它并信任它
    • tests/ 目录可以通过保存与输出(来自之前的 R CMD check 运行)进行比较来提供单元测试的简化版本,这很有用,但正确的单元测试更好
    • 特别是对于带有目标代码的包,我更喜欢启动新的 R 会话,littler 让这很容易:r -lfoo -e'bar(1, "ab")' 启动一个 R 会话,加载 foo 包并评估给定的表达式(这里是一个函数 @987654335 @ 带有两个参数)。这与R CMD INSTALL 相结合,提供了一个完整的测试周期。

    【讨论】:

    • 是否使用任何单元测试和代码覆盖工具?您用来帮助您高效编码的其他包和脚本呢?
    • 如果您查看我的包,您会发现 RUnit 的使用相当广泛。我没有部署任何显式代码覆盖工具。
    • 您当时使用哪些分析工具? :)
    • 我在“带 R 的 HPC 简介”演示文稿中详细(并通过示例)谈到了这一点,请参阅我的网站以获取 pdf 副本。
    • 这是该演讲的链接,以防有人需要dirk.eddelbuettel.com/papers/ismNov2009introHPCwithR.pdf
    【解决方案3】:

    我已经编写了太多的包,所以为了让事情变得易于管理,我在基础设施包上投入了大量时间:这些包帮助我使我的代码更健壮并帮助其他人更容易使用。其中包括:

    • roxygen2(与 Manuel Eugster 和 Peter Danenberg 合作),它允许您将文档保存在它所记录的函数旁边,这样我就更有可能保持它是最新的。 roxygen2 还具有许多旨在最大限度减少文档重复的新功能:模板 (@template)、参数继承 (@inheritParams) 和函数系列 (@family) 等等。

      李>
    • testthat 自动测试我的代码。随着我编写代码的时间越来越少,这一点变得越来越重要:自动化测试会记住函数应该如何工作,即使我没有。

    • devtools 自动执行许多常见的开发任务(正如 Andrie 所提到的)。 devtools 的最终目标是让它像 R CMD check 一样在后台持续运行,并通知您出现问题的实例。

    • profr,尤其是未发布的interactive explorer,让我很容易找到代码中的瓶颈。

    • helpr(与 Barret Schloerke 合作)很快将支持 http://had.co.nz/ggplot2,它为 R 文档提供了优雅的 html 界面。

    有用的 R 函数:

    • apropos:我总是忘记有用函数的名称,apropos 帮助我找到它们,即使我只记得一个片段

    R 之外:

    • 我使用 textmate 编辑 R(和其他)文件,但我不认为它真的那么重要。选择一个并了解它的所有角落和缝隙。

    • 花点时间学习命令行。从长远来看,您可以采取任何措施来自动化您工作流程的任何部分。从命令行运行 R 会导致一个自然过程,每个项目都有自己的 R 实例;我经常一次运行 2-5 个 R 实例。

    • 使用版本控制。我喜欢gitgithub。同样,您使用哪种系统并不重要,但要掌握它!

    我希望 R 拥有的东西:

    • 代码覆盖率工具
    • 像 rake 或 jake 这样的依赖管理框架
    • 更好的内存分析工具
    • 用于描述数据帧(和其他数据源)的元数据标准
    • 用于描述和呈现各种输出格式的表格的更好工具
    • markdown 渲染包

    【讨论】:

    • 有趣——尤其是描述数据帧的元数据标准。这并不难 - 至少是照顾 80% 的初始削减。你在想什么使用场景?一个想法可能是可以附加到数据源的元数据数据框(具有严格的语义)。想法?
    • 命令行位怎么强调都不为过。拥有基本的 unix CLI 知识可以将他们的工作效率提高一个数量级。
    • @Krishna - 我更多地考虑像qnch这样的外部格式。
    • 对于dataframes的元数据信息,我们可以使用comment(dataframe$column)以正确的格式注释每一列吗?
    • 另外:我标记了这个问题,以便在它关闭后进行更多审查(在我看来,这是一个低效用/负效用社区不利行动)。这不能做成社区维基吗?意图是积极的:虽然标记可能看起来消极 - 我的意图不是影响 OP,而是结束。
    猜你喜欢
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 2016-08-18
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    相关资源
    最近更新 更多