What is the difference between running chunk and knitting it?

Hi. Is there documentation somewhere that explains the difference between running a chunk interactively in RStudio (pressing "run", "run all", etc) and pressing the "knit" button? It seems like some of the knitr settings are used with "run" but some are not. E.g.

---
output: html_document
---

```{r setup, include=FALSE}
library(knitr)
knit_hooks$set(myhook = function(before, options, envir) {
  if (options$eval) {
    if (before) {
      write(0, 'lock.file')
    } 
  }
})
opts_chunk$set(echo = TRUE, myhook = TRUE)
```

## R Markdown

```{r cars}
summary(cars)
```

When I knit, the lock file is created. When I run, it isn't. Just wondering, and if someone has a suggestion on how to automatically wrap the execution of chunks in another way so it works whether running or knitting, I'd be happy to know. Thanks.

TLDR

In short, running your chunk just defines the function. Knitting the document causes knitr to execute the function hook you've defined.

Explanation

Running a chunk executes it in your current interactive environment. After running this chunk, you should be able to see that knit_hooks now contains a function myhook. The chunk defines a function. It does not execute that function.

That hook function is executed by knitr when it runs. So when you knit the document, knitr checks for any hook functions that are defined and executes them.

A Chunk that will write a file either way

Consider a simpler chunk. When run or knit, this should write a file to disk.

```{r simple, include=FALSE}
write(0, 'simple.file')
```

That's not what I want. I'd need to add one of these include=FALSE chunks before and after every chunk I'm really interested in. And the "run all" or "run until this chunk" buttons would work, but it'd still be possible to press run on any chunk in the document independently of these sort of hidden "setup/teardown" chunks.

Is there anything in the rstudioapi package that's along these lines? I just find it curious because clearly RStudio is using knitr options somehow. I tried to redefine the hook for evaluate() and that didn't do anything either. I tried something like:

```{r setup}
library(knitr)
knit_hooks$set(evaluate = function(...) {
  # pre-chunk
  write(0, 'lock.file')
  evaluate::evaluate(...)
  # post-chunk
})
```

Setup/Teardown when run or knit

I don't think you're going to be able to use knitr's hooks and have them automagically execute before and after when just running chunks.

If you don't need to manipulate any of the chunk options or names in your setup/teardown you could define your setup/teardown functions in a single chunk at the top of your document, and subsequently explicitly call them.

``` {r function_defs, include=FALSE}
setup <- function() {
  # Work
  invisible(result)
}
teardown <- function() {
  # Work
  invisible(result)
}
```

```{ r report, include=TRUE}
  setup()
  summary(cars)
  teardown()
```

Knitr options when running chunks?

What knitr options are you seeing Rstudio incorporate when running chunks?

You can set all kinds of plot or table options and these have an impact interactively. You can set eval=FALSE and it'll not run the chunk in "run all". The documentation:

mentions a lot of options that will work in RStudio. I would like to know about what won't work and why not. When I read sections of the knitr book and implement it in RStudio and it doesn't work because the "Run" button is an entirely different mechanism, I'm more likely to take it out and not use it, rather than change my workflow and just press knit over and over.

I don't think it's "automagical" at all if the run button already does a lot to mimic knitr. It's not clear to me what the limits are of RStudio's interactive rendering.

I ran across this:

I guess it's the same issue.

I'm seeing RStudio respecting some of the chunk options, but not operating on the knitr options at all. Compare the run and knit outputs of the following chunks.

```{r pressure1, echo=FALSE, dev.args=list(bg='yellow'), fig.width=5}
knitr::opts_chunk$set(comment=NA, fig.asp=1, dev.args=list(bg='gray'))
plot(pressure)
```

```{r pressure2, echo=TRUE, fig.width=6}
knitr::opts_chunk$set(comment=NA, fig.asp=.75, dev.args=list(bg='gray'))
plot(pressure)
```

Only fig.width gets used by RStudio when running the chunks interactively. When using knitr to generate a document, the pressure1 figure is square and yellow while the pressure2 figure is preceded by the code being echoed and is a grey rectangular figure.

It doesn't appear that RStudio is using knitr to render the chunks, so I wouldn't bet on hooks being available.

1 Like

I agree that I wish I knew of some clear documentation on which chunk options the various Run buttons take into consideration, and under what circumstances. I'm sorry that this answer isn't going to provide much clarity there. :pensive:

I think some of the trouble here stems from the fact that runnable cells are a notebook feature that originated with the R Notebook format, and were then extended to regular R Markdown documents. The conceptual model for non-notebook R Markdown documents has always been that you will in fact press the knit button over and over (i.e. compile the entire document in a batch mode via render::rmarkdown(), which is invoked by the Knit button).

If you want to understand more deeply how R Markdown and knitr relate to computational notebooks, I highly recommend this (long!) post:

A couple of excerpts that start to get at the bigger issues behind the design decisions I think you're bumping up against:

I care a lot about reproducibility, so does RStudio, and we have made a decision on Day One that R Markdown documents should be compiled in new R sessions, which will (mostly) get rid of the problems of hidden state and out-of-order execution. Although many users have complained about it and wanted to run R Markdown documents in the current R session instead, we have never changed the decision. After we created R Markdown notebooks, we have also been constantly alerting users about the potential problems of notebooks. For example, in our book “R Markdown: The Definitive Guide”, we emphasized this issue over and over again:

[…] Again, for the sake of reproducibility, you will need to compile the whole document eventually in a clean environment.

(link to section)

R Markdown notebooks are just plain text R Markdown documents. The “notebook” is only a special execution mode of R Markdown documents (as we mentioned in the book “R Markdown: The Definitive Guide”). Or you may treat it as a by-product instead of a product. If you like it, use it; if you don’t, use the original R Markdown mode, i.e., the batch mode—click the Knit button to compile the whole document in a new R session every time.

(link to section)

Being able to run individual cells in non-notebook R Markdown documents is then a convenience for quick interactive iteration, but not meant to be equivalent to compiling. But then things get muddy because the inline chunk output seems to (sort of) pay attention to (some of) the chunk options.

If you run these examples with the "Chunk Output in Console" option set (gear menu at top of document, or there's also a Global Option for it), you'll notice that none of the chunk options has any effect. And you don't really expect it to, because it's obvious that the code is just running in the console like usual. This is maybe a clearer paradigm? But inline chunk output is undeniably nice in its own ways. There's currently a discussion on the RStudio IDE GitHub about whether inline chunk evaluation is the correct default for non-notebook R Markdown documents, and which explains some more of the history:

TL;DR

Despite the way that inline chunk output pays attention to some of the chunk options, running chunks isn't the same thing as rmarkdown::render() (which is what the Knit button actually calls), so I agree with @grosscol that you're going to have to roll your own setup/teardown system that will work when running individual chunks. You might be able to do something clever by testing for interactive() (which returns TRUE when using Run buttons, FALSE when compiling), but I suspect it's still going to feel clunky and duplicative.

The other alternative seems to be always compiling the document instead of using the Run buttons — but if you hate clicking as much as Yihui does, maybe xaringan::inf_mr() can help? (it's not just for slides!)

2 Likes

I certainly made peace with the reality I couldn't quite do what I was hoping to. If the RStudio notebook is an approximation, then that's fine. I was convinced knitr was involved more than it is. I don't think all my confusion is cleared but anyway it's still nice to not be wasting time trying to figure out why I can't get something to work. That long blog post is really good. It's quite a ramble but really shines some light on some nuts and bolts that I've been confused about. I don't think that's the first time I've been pointed to something like that... something just outside of where I'm typically looking. Thanks. I need to bookmark more blogs and stuff coming out of the R/RStudio heavy-hitters. I usually see this stuff a lot later.

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.