iago
iago

Reputation: 3266

How to control R warnings in knitr to rmarkdown

I have a chunk with a loop which produces images and results of a linear model. Sometimes the model produces non-convergence warnings. Images and results become fully disorganised if I let warning=TRUE as chunk condition. But I want to print the warning, so I try it through cat(names(last.warning)) (thanks to this SO). Then I get the next error when knitr:

Error in eval(expr, envir, enclos) : object 'last.warning' not found
Calls: <Anonymous> ... handle -> withCallingHandlers -> withVisible -> eval -> eval

Execution halted

What can I do?

Thank you!

Upvotes: 2

Views: 609

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 174586

The idea is to try to catch the warning and print its message. The following example is inside a suppressWarnings call, which should have the same effect as being inside a warning = FALSE chunk.

Here the actual code I want to run is just as.numeric(c("1", "A")). I want to print any warnings the code generates despite it being inside a suppressWarnings block, and I also want to print the result of the code:

suppressWarnings({

#--- Code chunk ----------------------------------------------------------#  
  
  withCallingHandlers(
        expr    = as.numeric(c("1", "A")), 
        warning = function(w) cat("** warning:", w$message, "**\n\n")
  )

#--- End of code chunk ---------------------------------------------------#

})

#> ** warning: NAs introduced by coercion **
#> 
#> [1]  1 NA

Edit

Here is a reproducible Rmd that shows how to display any warnings optionally after the result of the calculation is printed:

---
title: "test"
author: "Allan Cameron"
date: "27 November 2020"
output: html_document
---

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

 ## Print warning after output

 ```{r test, warning=FALSE}
   withCallingHandlers(
        expr    = as.numeric(c("1", "A")), 
        warning = function(w) warn <<- paste("** warning:", w$message, "**\n\n")
   )
```

```{r print_warn, echo=FALSE}
  if(exists("warn")) cat(warn)
```

This produces:

enter image description here

Upvotes: 2

Related Questions