如何在编织Rmd文档时请求提前退出?

jen*_*yan 40 markdown r knitr

假设您有一个不会干净利落的R降价文档.

我知道您可以将knitrchunk选项error设置TRUE为请求继续进行评估,即使存在错误也是如此.您可以通过error = TRUE或以更全局的方式为单个块执行此操作knitr::opts_chunk$set(error = TRUE).

但有时会出现针对编织过程仍然致命的错误.我最近遇到的两个例子:当RStudio不可用时,尝试unlink()当前的工作目录(oops!)并rstudioapi::getVersion()从内联R代码调用.是否对这些类型的错误进行了一般描述,即那些超出范围的错误error = TRUE?有没有办法容忍内联R代码与块中的错误?

此外,还有更多官方方法可以提前停止编织或在这种情况下自动调试吗?

Yih*_*Xie 34

要从编织过程中提前退出,您可以knitr::knit_exit()在源文档中的任何位置使用该函数(在代码块或内联表达式中).一旦knit_exit()被调用,knitr将忽略文档的所有其余内容并写出它到目前为止收集的结果.

目前无法容忍内联R代码中的错误.您需要确保内联R代码始终运行且没有错误1.如果确实发生错误,您应该看到表单中控制台中knitr日志产生错误的行范围Quitting from lines x1-x2 (filename.Rmd).然后你可以到文件filename.Rmd,看看有什么不对从线x1x2.同样的事情适用于具有chunk选项的代码块error = FALSE.

除了上面提到的错误类型之外,找到问题的根源可能很棘手.例如,当你无意中unlink()当前目录时,它不应该停止编织过程,因为unlink()无论如何都成功了.您可能会在编织过程后遇到问题,例如,LaTeX/HTML无法找到输出图形文件.在这种情况下,您可以尝试knit_exit()逐个应用于文档中的所有代码块.实现此目的的一种方法是设置一个块钩子以knit_exit()在某个块之后运行.下面是使用线性搜索的示例(您可以通过使用二分法来改进它):

#' Render an input document chunk by chunk until an error occurs
#' 
#' @param input the input filename (an Rmd file in this example)
#' @param compile a function to compile the input file, e.g. knitr::knit, or
#'   rmarkdown::render
knit_debug = function(input, compile = knitr::knit) {
  library(knitr)
  lines = readLines(input)
  chunk = grep(all_patterns$md$chunk.begin, lines)  # line number of chunk headers

  knit_hooks$set(debug = function(before) {
    if (!before) {
      chunk_current <<- chunk_current + 1
      if (chunk_current >= chunk_num) knit_exit()
    }
  })

  opts_chunk$set(debug = TRUE)

  # try to exit after the i-th chunk and see which chunk introduced the error
  for (chunk_num in seq_along(chunk)) {
    chunk_current = 0  # a chunk counter, incremented after each chunk
    res = try(compile(input))
    if (inherits(res, 'try-error')) {
      message('The first error came from line ', chunk[chunk_num])
      break
    }
  }
}
Run Code Online (Sandbox Code Playgroud)
  1. 这是设计的.我认为拥有error = TRUE代码块是个好主意,因为有时我们想要显示错误,例如,出于教学目的.但是,如果我也允许内联代码出错,作者可能无法识别内联代码中的致命错误.内联代码通常用于嵌入内联,如果内联值是错误,我认为这没有多大意义.想象一下报告中的一个句子The P-value of my test is ERROR,如果knitr没有发出错误信号,则需要作者非常仔细地阅读报告输出以发现此问题.我认为不得不依靠人眼来发现这样的错误是一个坏主意.


pte*_*tor 9

恕我直言,难以调试Rmd文档是一个警告,有些事情是错误的.我有一个经验法则:在Rmd 做重物.在Rmd内渲染,渲染.这使得Rmd代码变得简单.

我的大型R程序看起来像这样.

data <- loadData()
analytics <- doAnalytics(data)
rmarkdown::render("theDoc.Rmd", envir=analytics)
Run Code Online (Sandbox Code Playgroud)

(在这里,doAnalytics返回一个列表或环境.该列表或环境被传递给通过的RMD文件ENVIR参数,使得可用的文档里面的分析计算结果.)

doAnalytics功能做了复杂的计算.我可以使用常规工具调试它,我可以轻松检查其输出.当我调用rmarkdown :: render时,我知道硬件工作正常.Rmd代码只是"打印此"和"格式化",易于调试.

这种责任分工对我很有帮助,我可以推荐它.特别是与调试隐藏在动态渲染文档中的复杂计算的令人费解的任务相比.

  • 另一方面是,如果所有内容都在 .Rmd 中,那么您将拥有一个文档来显示您的(例如)科学论文是如何生成的,这对于可重复的研究很有好处。也许解决方案是将分析放入 Rmd 中的函数中,以便可以在命令行中运行和调试它们。 (2认同)