Code execution

\t

When you render a learnr tutorial, R Markdown will start a fresh R session and then evaluate all of the non-exercise related knitr chunks in the global environment of that R session. This includes the global setup chunk.

# the setup chunk
library(learnr)
(a <- Sys.time())
environment()
x <- 1
environment()
ls.str(environment())

Exercise execution

When you run an exercise chunk, learnr will create a new environment to run the code in. The parent of this environment will be the global environment. As a result, the exercise code will have access to every object created in a non-exercise chunk---even if the object is created in a non-exercise chunk that appears after the exercise.

(z <- x + y)
environment()
parent.env(environment())

Note that the chunk that creates y appears afer the exercise:

y <- 1
environment()

\t

Everytime you run an exercise, R Markdown creates a new child environment of the global environment to run the code in. In fact, R Markdown will create a new child environment each time you run the same exercise.

environment()
parent.env(environment())

\t

This constraint is imposed so that users can execute exercises in any order (i.e. correct execution of one exercise never depends on completion of a prior exercise).

z

Exercise setup

\t

Sometimes an exercise will require an object that is not created in a non-exercise chunk. For example, an exercise may require an object that was created in a previous exercise, like z.

You can provide these objects by creating a setup chunk for the exercise. R Markdown will evaluate the setup chunk before it evaluates the code in the exercise.

There are two ways to provide setup chunks:

1. The -setup suffix

Create a setup chunk that’s specific to an exercise using a -setup chunk suffix. To do this give your exercise chunk a label (e.g. filter) then add another chunk with the same label plus a -setup suffix (e.g. filter-setup).

When you run the exercise R Markdown will proceed in the normal way. It will:

  1. Create a new environment to run the exercise code in
  2. Set the parent of that environment to the global environment

R Markdown will then run the code in the setup chunk before running the code in the exercise chunk.

\t

To illustrate, the exercise chunk below is labeled s in the .rmd file. It is accompanied by a setup chunk labeled s-setup that looks like this.

s <- 1
environment()
parent.env(environment())
s
environment()
parent.env(environment())
s <- 1
environment()
parent.env(environment())

\t

Note that my description of the setup chunk above was not the setup chunk. I made a duplicate, unevaluated chunk to show you what my setup chunk looked like. Why? Because R Markdown treats setup chunks in a special way. R Markdown will not:

  1. Evaluate a setup chunk when it renders the document
  2. Display the content of a setup chunk within the document

Moreover, when you use the -setup method to create a setup chunk, R Markdown will only evaluate the setup code when you run the exercise that the setup code is associated with. To illustrate, this new exercise labelled t will fail because it is not associated with the setup chunk labelled s-setup.

s

2. The exercise.setup option

You can use an exercise's exercise.setup chunk attribute to provide the label of another chunk that will perform setup tasks. When you do, this chunk becomes a setup chunk associated with the exercise. Importantly, R Markdonw will not evaluate the chunk upon render nor show its results within the document.

This method let's you associate the same setup chunk with multiple exercises.

To illustrate, I've created a chunk labelled u that looks like this

# chunk labelled u
u <- 100
environment()
parent.env(environment())
u <- 100
environment()
parent.env(environment())

The first two of these exercises include the chunk attribute exercise.setup = "u", but the last does not (you will need to examine the .rmd file to see these attributes). As a result, the first two exercises will run successfully, but the last will not.

u
environment()
parent.env(environment())
u
environment()
parent.env(environment())
u
environment()
parent.env(environment())

What ifs

Why not both?

If you specify an exercise.setup chunk attribute and create a -setup chunk for the same exercise, R Markdown will ignore the -setup chunk.

At the moment, you also cannot specify more than one chunk in the exercise.setup chunk attribute. If you do, R Markdown will ignore all setup chunks listed in the attribute for that exercise.

What about dependson?

R Markdown (that is knitr) chunks also recognize a dependson chunk attribute. dependson is used to help knitr update cached results in documents that use caching. You cannot use dependson as a substitute for a setup method.

If you set the dependson chunk attribute for an exercise, R Markdown will treat the specified chunk as a normal non-exercise chunk. It will be evaluated when the document is rendered, and its results will be included in the document in the normal way.

For example, the exercise below lists this chunk as a dependson.

v <- 50
environment()
v
environment()
parent.env(environment())


rstudio-education/grader documentation built on July 6, 2023, 8:48 a.m.