26

Based on some simple tests, interactive() is true when running code within rmarkdown::render() or knitr::knit2html(). That is, a simple .rmd file containing

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

gives an HTML file that reports TRUE.

Does anyone know of a test I can run within a code chunk that will determine whether it is being run "non-interactively", by which I mean "within knit2html() or render()"?

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453

3 Answers3

39

As Yihui suggested on github isTRUE(getOption('knitr.in.progress')) can be used to detect whether code is being knitted or executed interactively.

CL.
  • 14,577
  • 5
  • 46
  • 73
  • 1
    why is `knitr.in.progress` not set (i.e. `isTRUE(getOption('knitr.in.progress'))` returning `FALSE`) when knitting in a shell script using `Rscript -e "rmarkdown::render(...)"`? @yihui-xie ? – Salim B Nov 04 '18 at 23:44
  • 2
    Have you tried `!is.null(getOption("knitr.in.progress"))`? – MS Berends Jul 06 '21 at 07:27
6

A simple suggestion for rolling your own: see if you can access current output format:

```{r, echo = FALSE}
is_inside_knitr = function() {
        !is.null(knitr::opts_knit$get("out.format"))
}
```

```{r}
is_inside_knitr()
```

There are, of course, many things you could check--and this is not the intended use of these features, so it may not be the most robust solution.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • This has to be combined with at least `&& !interactive()` then, because when I run `length(knitr::opts_current$get())` just in my current interactive R session, it returns `53`. Bottom line - this method is not very effective. – MS Berends Jul 06 '21 at 07:24
  • 1
    Hmmm, yes. I tested this at the time - I won't what has change. It does seem like my second suggestion using `out.format` is still effective - I'll remove the other suggestion. – Gregor Thomas Jul 06 '21 at 15:59
3

I suspect (?) you might just need to roll your own.

If so, here's one approach which seems to perform just fine. It works by extracting the names of all of the functions in the call stack, and then checks whether any of them are named "knit2html" or "render". (Depending on how robust you need this to be, you could do some additional checking to make sure that these are really the functions in the knitr and rmarkdown packages, but the general idea would still be the same.)

```{r, echo=FALSE}
isNonInteractive <- function() {
    ff <- sapply(sys.calls(), function(f) as.character(f[[1]]))
    any(ff %in% c("knit2html", "render"))
}
```

```{r}
print(isNonInteractive())
```
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455