假设您有一个R markdown文档,它将无法清晰呈现。
我知道您可以将knitr
块选项error
设置为TRUE
,以请求继续评估,即使存在错误也是如此。您可以通过error = TRUE
为单个块执行此操作,或者通过knitr::opts_chunk$set(error = TRUE)
以更全局的方式执行此操作。
但是有时仍然存在一些错误,这些错误对于编织过程仍然是致命的。我最近遇到的两个示例:尝试对当前工作目录进行unlink()
(哎呀!),以及在RStudio不可用时从内联R代码调用rstudioapi::getVersion()
。是否有对这类错误(即error = TRUE
所无法涵盖的错误)的一般描述?有没有办法容忍内联R代码和块中的错误?
此外,在这种情况下,还有更多官方方法可以提前停止编织或自动调试吗?
最佳答案
要提前退出编织过程,可以在源文档中的任何位置(在代码块或内联表达式中)使用knitr::knit_exit()
函数。调用knit_exit()
后, knitr 将忽略文档的所有其余部分,并写出到目前为止已收集的结果。
目前尚无法容忍内联R代码中的错误。您需要确保内联R代码始终运行无错误1。如果确实发生错误,则应该从控制台中的 knitr 日志中以Quitting from lines x1-x2 (filename.Rmd)
的形式查看产生错误的行范围。然后,您可以转到文件filename.Rmd
,查看从x1
到x2
的行出了什么问题。具有块选项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
}
}
}
error = TRUE
是个好主意,因为有时我们出于教学目的例如会显示错误。但是,如果我也允许内联代码出现错误,那么作者可能无法识别内联代码中的致命错误。内联代码通常用于内联嵌入值,如果内联值有错误,我认为这没有多大意义。想象一下报告中的一个句子,例如The P-value of my test is ERROR
,如果 knitr 没有发出错误信号,它将要求作者非常仔细地阅读报告输出以发现此问题。我认为必须依靠人眼才能发现这种错误是一个坏主意。 关于r - 编织Rmd文档时如何请求提前退出?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33705662/