首页 > 解决方案 > 使用 knitr 获取来自 R 的错误消息,因为它们本机出现在 R 会话中

问题描述

我想使用 Rmarkdown 构建一个 html 文档,其中可以显示来自 R 的错误消息,因为它们确实出现在 R 交互式会话中。

这个问题类似,但不要求错误消息与交互式会话中的显示完全相同:我尝试使用error=TRUE给定的块,错误的前缀为Error in eval(expr, envir, enclos):

使用以下块:

```{r, error=TRUE}
notexistingvariable
```

我预计:

Error: object 'notexistingvariable' not found

我得到:

Error in eval(expr, envir, enclos): object 'notexistingvariable' not found

我尝试添加该results="asis"选项,但这在这里没有效果。我认为这仅适用于非错误输出。


尝试使用wrap.error

正如答案中所建议的,我尝试设置自定义wrap.error功能。

test.Rmd

---
title: "test"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)

wrap.error <- function(x, options) {
  # x is an error object, with components "call" and "message".  Ignore
  # the call, but wrap the result like code:
  paste0("```\n## Error: ", x$message, "\n```")
}
```

```{r, error=TRUE}
notexistingvariable
```

转换为html:

$ R -e "rmarkdown::render('test.Rmd',output_file='test.html')"

R version 3.5.1 (2018-07-02) -- "Feather Spray"
Copyright (C) 2018 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> rmarkdown::render('test.Rmd',output_file='test.html')


processing file: test.Rmd
  |................                                                 |  25%
  ordinary text without R code

  |................................                                 |  50%
label: setup (with options) 
List of 1
 $ include: logi FALSE

  |.................................................                |  75%
  ordinary text without R code

  |.................................................................| 100%
label: unnamed-chunk-1 (with options) 
List of 1
 $ error: logi TRUE


output file: test.knit.md

/usr/bin/pandoc +RTS -K512m -RTS test.utf8.md --to html4 --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output test.html --smart --email-obfuscation none --self-contained --standalone --section-divs --template /home/bli/R/x86_64-pc-linux-gnu-library/3.5/rmarkdown/rmd/h/default.html --no-highlight --variable highlightjs=1 --variable 'theme:bootstrap' --include-in-header /tmp/RtmpAoBtc7/rmarkdown-str53186fa5c04d.html --mathjax --variable 'mathjax-url:https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML' 

Output created: test.html
> 
> 

test.html文件如下所示:

用firefox渲染html


wrap.simpleError正如现在更新的答案所建议的那样,使用是有效的。

标签: rr-markdownknitr

解决方案


(更新以反映 R 3.5.x 的变化)

您可以为输出设置自定义渲染器(请参阅 参考资料vignette("knit_print")),但我认为发生错误时不会调用它们。在这种情况下调用通用wrap()函数。knitr定义了一个wrap.error()方法,在 R 3.5.0 之前,它可以被用户覆盖。但是,在最新版本的 R 中,包中定义的方法优先于用户定义的方法,因此它不再起作用。

但是,仍然有一些错误的解决方案。对于问题中的示例,创建的错误对象具有 class c("simpleError", "error", "condition"),并且knitr没有定义wrap.simpleError()方法。您可以定义一个,并覆盖其处理。

你这样做:

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)

wrap.simpleError <- function(x, options) {
  # x is an error object, with components "call" and "message".  Ignore
  # the call, but wrap the result like code:
  paste0("```\n## Error: ", x$message, "\n```")
}
```

```{r, error=TRUE}
notexistingvariable
```

这将显示如下结果: 在此处输入图像描述

还有一个输出钩子来处理错误:见https://yihui.name/knitr/hooks/wrap.error但是,当消息已经形成时,它似乎是在之后调用的。您可以使用以下代码编辑该消息以删除您不想要的部分:

```{r}   
knitr::knit_hooks$set(error = function(x, options) {
  paste0("```\n", 
         sub(" in eval(expr, envir, enclos)", "", x, fixed = TRUE),
         "\n```")
})
```e

这可能比这种方法更健壮,如果曾经定义过这样的wrap.simpleError方法,它将停止工作。它还将处理所有错误,而不仅仅是错误。它的缺点是可能更难对其进行自定义以处理不同类型的错误,并且可能无法在“错误输入”被翻译成其他语言的不同语言环境中工作。knitrwrap.simpleError"simpleError"


推荐阅读