要尽早退出编织过程,可以在源文档的任何位置(在代码块或内联表达式中)使用函数knitr::knit_exit()
.调用knit_exit()
后,knitr将忽略文档的所有其余部分,并写出迄今为止收集到的结果.
目前无法容忍内联R代码中的错误.您需要确保内联R代码总是在没有错误的情况下运行1.如果确实发生了错误,您应该在控制台中的表格Quitting from lines x1-x2 (filename.Rmd)
的knitr日志(log)中看到产生错误的行的范围.然后你可以转到文件filename.Rmd
,看看x1
到x2
之间的行有什么问题.同样的事情也适用于使用chunk选项error = FALSE
的代码块.
除了上面提到的错误类型之外,找到问题的根源可能很困难.例如,当你无意中 Select 了当前目录时,它不应该停止编织过程,因为unlink()
还是成功了.在编织过程之后,您可能会遇到问题,例如LaTeX/HTML无法找到输出的图形文件.在这种情况下,您可以try 将knit_exit()
逐个应用于文档中的所有代码块.实现这一点的一种方法是设置一个chunk hook,在某个chunk之后运行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
个是个好主意,因为有时我们想要显示错误,例如,出于教学目的.然而,如果我也允许内联代码出现错误,作者可能无法识别内联代码中的致命错误.内联代码通常用于嵌入values内联,如果内联值是一个错误,我认为这没有多大意义.想象一下The P-value of my test is ERROR
这样的报告中的一句话,如果knitr没有发出错误信号,那么作者需要非常仔细地阅读报告输出,才能发现这个问题.我认为依靠人眼来发现这样的错误是个坏主意.