将错误消息捕获为R中的字符串 [英] Capture Error Messages as Character String in R

查看:66
本文介绍了将错误消息捕获为R中的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想捕获由我的R代码返回的字符串中的错误消息.

I would like to capture error messages that are returned by my R code in a character string.

此线程说明如何捕获功能的错误消息.但是,当我尝试捕获函数外部的错误消息时,错误消息的格式将有所不同.

This thread explains how to capture error messages of functions. However, when I try to capture the error messages outside of functions, the error message is formatted differently.

考虑以下示例R代码:

5 5
# Error: unexpected numeric constant in "5 5"

如果我执行之前的R代码,则RStudio控制台将返回错误消息 Error:"5 5"中的意外数字常量.

If I execute the previous R code, the RStudio console returns the error message Error: unexpected numeric constant in "5 5".

但是,如果我尝试捕获此输出,则错误消息看起来会有所不同:

However, if I try to capture this output, the error message looks differently:

library("evaluate")

evaluate("5 5")[[2]]
# <simpleError: <text>:1:3: unexpected numeric constant
# 1: 5 5
# ^>

我的预期输出是一个包含以下字符串的数据对象:

My expected output is a data object containing the following character string:

my_output <- 'Error: unexpected numeric constant in "5 5"'
my_output
# [1] "Error: unexpected numeric constant in \"5 5\""

问题:如何将R代码的错误另存为字符串?

推荐答案

我尝试编写一个更新我的R代码的函数,以便所有RStudio控制台输出显示为代码中的注释.

I try to write a function that updates my R code so that all RStudio console output is shown as a comment within the code.

我认为 reprex 包和R Markdown在做什么想要.

I think the reprex package and R Markdown are doing what you want.

您可以测试语法,并与 pander 包来处理在解析器级别发生的错误. pander 不会产生确切的控制台错误,但可以与 reprex 和R markdown一起使用.

You can test the syntax and combine with pander package to deal with errors that occur at the parser level. pander does not produce the exact console error but works with reprex and R markdown.

带有reprex软件包

test_eval <- function(text_in){
  if(class(try(parse(text = text_in),silent=TRUE)) == "expression") {
    eval(parse(text = text_in))
  } else {
    x <- pander::evals(text_in)[[1]]$msg$errors
    x <- paste0(tolower(substr(x, 1, 1)), substr(x, 2, nchar(x)))
    x <- paste("Error:", x)
    x <- qdapRegex::rm_between(x, "at", ":", extract=FALSE, replacement="in")
    x <- gsub("` ", "\"", x)
    x <- gsub("`", "\"", x)
    message(x)
  }
}

test_eval("5 5")
#> Error: unexpected numeric constant in "5 5"
test_eval("\"a\" \"a\"")
#> Error: unexpected string constant in ""a" "a""
test_eval("head(iris)")
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9         3.0          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5          5.0         3.6          1.4         0.2  setosa
#> 6          5.4         3.9          1.7         0.4  setosa
test_eval("list()[[0]]")
#> Error in list()[[0]]: attempt to select less than one element in get1index <real>
test_eval("as.Date(10101)")
#> Error in as.Date.numeric(10101): 'origin' must be supplied
test_eval("library('ggplot2')")
test_eval("data <- data.frame(x = LETTERS[1:5], y = c(3, 1, 6, 3, 5))")
test_eval("ggplot(data, aes(x, y)) + geom_point() + geom_line()")
#> Error:   You're passing a function as global data.
#>   Have you misspelled the `data` argument in `ggplot()`

带有R Markdown

---
title: Test
output:
  html_document: default
---

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

```{r, collapse=TRUE, error=TRUE}
test_eval <- function(text_in){
  if(class(try(parse(text = text_in),silent=TRUE)) == "expression") {
    eval(parse(text = text_in))
  } else {
    message(paste("Error:", pander::evals(text_in)[[1]]$msg$errors))
  }
}

test_eval("5 5")
test_eval("a a")
test_eval("head(iris)")
test_eval("list()[[0]]")
test_eval("as.Date(10101)")
test_eval("library('ggplot2')")
test_eval("data <- data.frame(x = LETTERS[1:5], y = c(3, 1, 6, 3, 5))")
test_eval("ggplot(data, aes(x, y)) + geom_point() + geom_line()")
```

test_eval <- function(text_in){
  if(class(try(parse(text = text_in),silent=TRUE)) == "expression") {
    eval(parse(text = text_in))
  } else {
    x <- pander::evals(text_in)[[1]]$msg$errors
    x <- paste0(tolower(substr(x, 1, 1)), substr(x, 2, nchar(x)))
    x <- paste("Error:", x)
    x <- qdapRegex::rm_between(x, "at", ":", extract=FALSE, replacement="in")
    x <- gsub("` ", "\"", x)
    x <- gsub("`", "\"", x)
    message(x)
  }
}

test_eval("5 5")
## Error: unexpected numeric constant in "5 5"
test_eval("\"a\" \"a\"")
## Error: unexpected string constant in ""a" "a""
test_eval("head(iris)")
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
test_eval("list()[[0]]")
## Error in list()[[0]]: attempt to select less than one element in get1index <real>
test_eval("as.Date(10101)")
## Error in as.Date.numeric(10101): 'origin' must be supplied
test_eval("library('ggplot2')")
test_eval("data <- data.frame(x = LETTERS[1:5], y = c(3, 1, 6, 3, 5))")
test_eval("ggplot(data, aes(x, y)) + geom_point() + geom_line()")
## Error:   You're passing a function as global data.
##   Have you misspelled the `data` argument in `ggplot()`

reprex 软件包和R Markdown使用的是 evaluate 软件包.也许可以在此程序包中进行测试.Github上的新问题: https://github.com/r-lib/evaluate/issues/101 .

reprexpackage and R Markdown are using evaluate package. Maybe the test could be done in this package. New issue on Github: https://github.com/r-lib/evaluate/issues/101.

还用 pander 打开了一个问题: https://github.com/Rapporter/pander/issues/349 .

Also opened an issue with pander: https://github.com/Rapporter/pander/issues/349.

此致

这篇关于将错误消息捕获为R中的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆