2

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?

7
  • I don't think that question makes sense. There's no such thing as an "R Markdown" context as far as the code is concerned. When you run code in RStudio that happens to be in an Rmd file, you're just running code. You could tell if the currently active file in the editor has an Rmd extension, and maybe that's good enough for you, but it's not "an R Markdown context". Commented Feb 5, 2024 at 22:44
  • This shows you how to find the current file in the editor: stackoverflow.com/a/47045368/2554330 . Commented Feb 5, 2024 at 23:14
  • @user2554330 I have edited the question with screenshots (early on) to show the error that triggered this question. So, YES, Rstudio is quite aware of when code is run within an Rmd block versus within the console, even if both are being run interactively. Commented Feb 6, 2024 at 7:17
  • @user2554330 Thanks for the lined question and answers. I tried them but at the very best, these are partial workarounds. They all assume that the code is being executed from a saved file (e.g., an Rmd file) and they try to infer the context by assuming it from the file extension. But a very real use case for which I want a solution is when someone copies code from a vignette or Rmd file without saving it and then runs it to try it out. (I do this very often.) My question is how to determine the Rmd context, even without a saved file. Commented Feb 6, 2024 at 7:35
  • I think your question should be more specific about detecting the presence or absence of global handlers. The error was "should not be called with handlers on the stack". So wouldn't it be simplest to test "are there handlers on the stack"? Apparently RStudio puts some handlers there when you run code as you did. So a test could be length(globalCallingHandlers()) > 0. Or maybe the error is about other kinds of handlers, and you should look for those. Commented Feb 6, 2024 at 10:01

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect! That's just what I was looking for. In fact, just getOption("rstudio.notebook.executing") is enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.