编制Rmd文件时如何申请提前退出?

编制Rmd文件时如何申请提前退出?,r,markdown,knitr,R,Markdown,Knitr,假设您有一个R标记文档,该文档将无法干净地呈现 我知道您可以将knitrchunk选项error设置为TRUE以请求继续评估,即使存在错误。您可以通过error=TRUE对单个块执行此操作,或者通过knitr::opts\u chunk$set(error=TRUE)以更全局的方式执行此操作 但有时也会出现一些错误,这些错误对编织过程来说仍然是致命的。我最近遇到了两个例子:尝试unlink()当前工作目录(oops!)和在RStudio不可用时从内联R代码调用rstudioapi::getVer

假设您有一个R标记文档,该文档将无法干净地呈现

我知道您可以将
knitr
chunk选项
error
设置为
TRUE
以请求继续评估,即使存在错误。您可以通过
error=TRUE
对单个块执行此操作,或者通过
knitr::opts\u chunk$set(error=TRUE)
以更全局的方式执行此操作

但有时也会出现一些错误,这些错误对编织过程来说仍然是致命的。我最近遇到了两个例子:尝试
unlink()
当前工作目录(oops!)和在RStudio不可用时从内联R代码调用
rstudioapi::getVersion()
。这些类型的错误是否有一般性描述,即
error=TRUE
无法达到的错误?有没有一种方法可以容忍内联R代码中的错误而不是块中的错误


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

要提前退出编织过程,可以在源文档的任何位置(在代码块或内联表达式中)使用函数
knitr::knit_exit()
。调用
knit_exit()
后,knitr将忽略文档的所有其余部分,并写出迄今为止收集到的结果

目前无法容忍内联R代码中的错误。您需要确保内联R代码始终无错误地运行1。如果确实发生错误,您应该从控制台中的knitr日志中看到产生错误的行的范围,格式为
从第x1-x2行退出(filename.Rmd)
。然后可以转到文件
filename.Rmd
,查看
x1
x2
之间的行有什么问题。使用chunk选项
error=FALSE
时,同样的情况也适用于代码块

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

#“逐块呈现输入文档,直到出现错误
#' 
#“@param输入输入文件名(本例中为Rmd文件)
#“@param编译一个函数来编译输入文件,例如knitr::knit,或
#'rmarkdown::render
knit_debug=函数(输入,编译=knitr::knit){
图书馆(knitr)
行=读取行(输入)
chunk=grep(所有模式$md$chunk.begin,行)#块头的行号
knit_hooks$set(调试=函数(之前){
如果(!之前){

chunk_currentIMHO,调试Rmd文档的困难是对出错的警告。我有一个经验法则:在Rmd之外进行繁重的工作。在Rmd内部进行渲染,并且只进行渲染。这使Rmd代码保持简单

我的大型R程序是这样的

data <- loadData()
analytics <- doAnalytics(data)
rmarkdown::render("theDoc.Rmd", envir=analytics)

数据很好的建议!我调试的文档需要使用
knitr::opts\u knit$set(root.dir=…)
,这是我通常避免的,就像瘟疫一样,并解释了我是如何无意中尝试删除工作目录的。有时调试确实必须在R标记域中进行。@ptetor-这很有趣,我从来没有考虑过。你能提供一个示例.R和.Rmd文件来说明如何在一个真实的示例中进行调试吗(iris、mtcars、flights等等)?谢谢你的建议,Stephen!我创建了一个要点来说明这个想法:另一方面,如果所有内容都在.Rmd中,那么你有一个单独的文档来显示你的(例如)生成了科学论文,这对于可复制的研究很好。也许一个解决方案是将您的分析放入Rmd中的函数中,这样就可以在命令行上运行和调试它们。
data <- loadData()
analytics <- doAnalytics(data)
rmarkdown::render("theDoc.Rmd", envir=analytics)