yihui / knitr

A general-purpose tool for dynamic report generation in R
https://yihui.org/knitr/
2.38k stars 872 forks source link

[bug] Rmd file does not respect options(warn = ) across chunks #2357

Open ppoyk opened 1 month ago

ppoyk commented 1 month ago

Hello, There seems to be an issue in how the R warning option (options()$warn) is handled inside an Rmd file. This might be related to an older issue https://github.com/yihui/knitr/issues/1425#issue-251433392

The warn option does not correctly persist across the Rmd file chunks.

Here is an example code to test the behaviour:

```{r part1}
f <- function(x) {warning("Warning raised!"); x}

options(warn = 0)
options()$warn
f(TRUE)

>[1] 0

>[1] TRUE

>Warning message:

>In f(TRUE) : Warning raised!

options(warn = 1)
options()$warn
f(TRUE)

options(warn = 2)

>[1] 1

>Warning in f(TRUE) : Warning raised!

>[1] TRUE

options()$warn
f(TRUE)

>[1] 1

>Warning in f(TRUE) : Warning raised!

>[1] TRUE

Last options()$warn reports value of 1, and thus the last call to f() does not raise an error, even though the option was explicitly set in the previous code chunk.
This should not be related to the `evaluate` package, as it only handles evaluation of a single chunk

I hope this is helpful.

---
Session info:

xfun::session_info("rmarkdown") R version 4.4.1 (2024-06-14 ucrt) Platform: x86_64-w64-mingw32/x64 Running under: Windows 11 x64 (build 22621), RStudio c(2024, 4, 2, 764)

Locale: LC_COLLATE=Finnish_Finland.utf8 LC_CTYPE=Finnish_Finland.utf8
LC_MONETARY=Finnish_Finland.utf8 LC_NUMERIC=C
LC_TIME=Finnish_Finland.utf8

Package version: base64enc_0.1.3 bslib_0.7.0 cachem_1.1.0 cli_3.6.3
digest_0.6.36 evaluate_0.24.0 fastmap_1.2.0 fontawesome_0.5.2 fs_1.6.4 glue_1.7.0 graphics_4.4.1 grDevices_4.4.1
highr_0.11 htmltools_0.5.8.1 jquerylib_0.1.4 jsonlite_1.8.8
knitr_1.48.1 lifecycle_1.0.4 memoise_2.0.1 methods_4.4.1
mime_0.12 R6_2.5.1 rappdirs_0.3.3 rlang_1.1.4
rmarkdown_2.27 sass_0.4.9 stats_4.4.1 tinytex_0.52
tools_4.4.1 utils_4.4.1 xfun_0.46 yaml_2.3.9

Pandoc version: 3.1.11



---

By filing an issue to this repo, I promise that

- [x] I have fully read the issue guide at https://yihui.org/issue/.
- [x] I have provided the necessary information about my issue.
    - If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    - If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included `xfun::session_info('knitr')`. I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: `remotes::install_github('yihui/knitr')`.
    - If I have posted the same issue elsewhere, I have also mentioned it in this issue.
- [x] I have learned the Github Markdown syntax, and formatted my issue correctly.

I understand that my issue may be closed if I don't fulfill my promises.
ppoyk commented 1 month ago

Could there be a solution similar to the par() function, where knitr has the possibility to set knitr::opts_knit$set(global.par = TRUE)? (StackOverflow discussion)

According to this other SO post, also setting other options() has inconsistent behaviour between running .Rmd chunks vs. knitting the whole document.

The behaviour should be consistent whether knitting or running as chunks (i.e. setting options() always correctly persists).

cderv commented 1 month ago

I tried this document

---
output: html_document
---

```{r part1}
f <- function(x) {warning("Warning raised!"); x}

options(warn = 0)
options()$warn
f(TRUE)
options(warn = 1)
options()$warn
f(TRUE)

options(warn = 2)
options()$warn
f(TRUE)

Then `knitr::knit("test.Rmd")` gets me this 

````markdown
---
output: html_document
---

``` r
f <- function(x) {warning("Warning raised!"); x}

options(warn = 0)
options()$warn
## [1] 0
f(TRUE)
## Warning in f(TRUE): Warning raised!
## [1] TRUE
options(warn = 1)
options()$warn
## [1] 1
f(TRUE)
## Warning in f(TRUE): Warning raised!
## [1] TRUE
options(warn = 2)
options()$warn
## [1] 2
f(TRUE)
## Error in f(TRUE): (converti depuis l'avis) Warning raised!

Doing `rmarkdown::render("test.Rmd")` gets me 

==> rmarkdown::render('C:/Users/chris/Documents/test.Rmd', encoding = 'UTF-8');

|.................... | 33% [part1]

processing file: test.Rmd

Error in f(): ! (converti depuis l'avis) Warning raised! Backtrace:

  1. global f(TRUE)

Quitting from lines 23-25 [ops-fail] (test.Rmd) Exécution arrêtée


So it seems to be working to me ... I am not sure what are the differences, I tried to use the same knitr and evaluate version as you shared. 

> Could there be a solution similar to the par() function, where knitr has the possibility to set knitr::opts_knit$set(global.par = TRUE)?

Note that you can use `R.options`: https://yihui.org/knitr/options/#other-chunk-options
This allows setting option for a cell only,  or could be set globally. But this would be no different of setting `options()` in the setup cell that would apply to all the cell in the document. 

````markdown
---
output: html_document
---

```{r}
options(dummy="I am global")
getOption("dummy")
getOption("dummy")

![image](https://github.com/user-attachments/assets/1ad011c8-ec71-42fb-8ff6-1ea8112748c7)

What would you expect differently ? 

> According to this [other SO post](https://stackoverflow.com/questions/69151368/how-to-make-optionswidth-60-persist-across-code-chunks-in-r-markdown-used-as), also setting other options() has inconsistent behaviour between running .Rmd chunks vs. knitting the whole document.

You refered to a 2 years old SO post with an answered (https://stackoverflow.com/a/69151906/3436535) explaining this only happens in Notebook mode. Meaning when cells are ran interactively, which is a feature of RStudio IDE or VSCODE extension, depending on what you are using. 

Are you report about using `knitr::knit()` or `rmarkdown::render()`, or is it about running cell interactively ? In the later case, this is a IDE issue regarding handling of R evaluation. 

Hope this helps
ppoyk commented 1 month ago

Sorry that I was unclear in my original post. The issue is precisely with running the .Rmd interactively, a chunk at a time or with Run all. (Inside RStudio)

As a copy of your example, when running interactively:

```{r}
options(dummy="I am global")
options(warn=2)
getOption("dummy")
getOption("warn")

>[1] "I am global"

>[1] 1

getOption("dummy")
getOption("warn")

>[1] "I am global"

>[1] 1


(When knitting, the output is as expected.)

Custom options behave correctly even in interactive mode, but something is tampering with the `warn` option.

Would you recommend moving this issue to [RStudio](https://github.com/rstudio/rstudio/issues)?
The issue list there seems hefty...
cderv commented 1 month ago

The issue is precisely with running the .Rmd interactively, a chunk at a time or with Run all. (Inside RStudio)

This is definitely a RStudio IDE discussion then. rmarkdown or knitr are not controlling how chunk are ran inside RStudio IDE.

Would you recommend moving this issue to RStudio?

Yes - this is on there end, and possibly warn options is something they need to control in interactive mode so that it behave correctly. IDK.

So opening an issue there is the right move for this - we can't do anything on our end here.