rr-markdownrstudioknitrinteractive

How to tell if code is running interactively within an R Markdown (Rmd) context?


My question is very similar to one that has been answered but with a crucial difference. There are several solutions to detecting if code is running non-interactively within an R Markdown (Rmd) context and they all seem to work pretty well. That is, when there is an Rmd script that is knit (for example, by clicking the "Knit" button in RStudio), those solutions show how to get the code to detect that the non-interactive knitting process is in progress. Unfortunately, none of them work when the user runs the same script interactively (e.g., by choosing the Run All command, Ctrl+Alt+R in RStudio). As distinct from Knit, which executes the knitting process in a special non-interactive R session, Run All executes the Rmd commands in the same interactive session in which the user currently is. My question is how to detect that interactive Rmd context.

My reason for this is that I want to call a function that invokes a global R handler, specifically progressr::handlers(global = TRUE). Global handler functions cannot run within Rmd contexts (probably because they are encased in a tryCatch block, which does not permit global handlers). So, I want to write my code such that it is aware that it is run from and Rmd block and then does not run in that case.

I did not realize it before, but apparently, the R context (or at least, RStudio, that I use) is indeed aware of when code is run interactively from the console versus from an Rmd block. Here is the error that triggered this question:

enter image description here

Yet the same line of code runs fine without error from the console (no output, but no error--it works in the background):

enter image description here

Here is a minimal reproducible Rmd file that tries all the solutions proposed for detecting non-interactive execution:

---
title: "Test Rmd self-awareness"
output: html_document
---

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

```{r}
interactive()
```

```{r}
isTRUE(getOption('knitr.in.progress'))
```

```{r}
knitr::opts_knit$get("out.format")
```

```{r}
sys.calls()
```

When I Knit that document, here's an extract of what I get:

enter image description here

rendered Rmd document

The solutions for non-interactive execution work: isTRUE(getOption('knitr.in.progress')) returns TRUE, knitr::opts_knit$get("out.format") gives a meaningful output ("markdown") and sys.calls() returns a call stack with rmarkdown::render() and knitr::knit(). But, notably, interactive() returns FALSE.

In contrast, here is the output when I interactively click Run All:

enter image description here

As you can see, when interactive() is TRUE, none of the solutions for non-interactive execution work: they return either FALSE or NULL. So, I cannot tell that these lines of code were executed from within Rmd blocks (which, as you can see, they all were).

So, can anyone help me figure out how to tell if code is running INTERACTIVELY within an R Markdown (Rmd) context?


Solution

  • You can use:

    identical(getOption("rstudio.notebook.executing"), TRUE)
    

    RStudio manages this option during chunk execution, and sets it to TRUE whenever execution is happening interactively within an R Markdown chunk.