How to make an interactive tutorial to teach R?

An overview

Learning is changing quickly, very quickly. With the advancement of technologies and with the help of unexpected game changer events, the future of learning is becoming online rather than onsite. This is particularly true for learning how to code (here is a nice book about Education in Data Science with R). Coding languages such as R or Python require a combination of contextual situations to be efficiently practiced:

  1. Learners need to see the output of running code. Classic slides lectures are good for general ideas but nothing can replace the direct feedback of run a code and comparing its output with expected results.

  2. Learners need to practice. Because the first will generally not produce the expected results, learners have to use the good old “die and retry” strategy to understand their errors. However it takes time and auto determination.

  3. Learners need to follow their own rhythm. Depending on learners’ previous experiences, the basics will be learnt faster or slower. All learners have their own pace.

Consequently, online learning is perfect for these 3 points. In the R community, I imagine that most people have actually learnt R online, at least it is my case.

Learning R online

There is a lot of amazing tutorials out there which can be accessed for free on coursera or udermy platforms for example or using blogs and online books. It is also very easy to create your own tutorial using {blogdown} or {bookdown} for example. A great talk entitled “How to Get Your Materials Online With R Markdown” recently introduced the different possibilities to share your own tutorial online (here are the video and the slides). However, few of these solutions are satisfying the first criteria. The ability to let the learners running the code by themselves usually imply that the learner has to run the code on a machine with the code and IDE required already installed.

One of these online learning platform is different, it allows the learner to watch a video or to read some slides and then to run the code via some exercises. I’ve learnt a lot from this platform but the access of the tutorials is not free and therefore not suitable for students.

Interactive tutorials R packages

The community around R has developed some amazing tools to create interactive tutorials which allow learners to run their own code (see here for example). There are maybe more of them but I am thinking of the {learnr} and {RTutor} packages (the {swirl} package also creates tutorials but these have to be used inside an IDE).

The {RTutor} package by Sebastian Kranz is showing the basics of interactivity. Wildly used for multiple tutorials (see GitHub README for list), it has paved the way for most recent alternatives. Here is a recent use of RTutor:

The {learnr} package by Schloerke, Allaire, and Borges (2020) is amazing. To be more familiar with the possibilities of {learnr}, you can have a look at the following {learnr} tutorial examples provided by RStudio ( here is the link to their code):

Another tutorial for sortable questions has been created by Andrie de Vries.

I think the R Set Up {learnr} is incredibly useful in a remote teaching context.

The RStudio education team have recently developed a suite of impressive interactive R tutorials called Primers based on their RStudio Cloud framework. I strongly recomand any R beginner to have a look at all these tutorials.

RStudio has currently developed 6 of these primers and plan to build even more of them.

{learnr} helps to create very neat interactive tutorials from a .Rmd file. Because I love Rmarkdown, I have created some of them already for my students:

The R community is also creating plenty more {learnr} tutorials, here is a list of the ones that I know of:

It is also possible to integrate the {learnr} package into a blogdown website and to create beautiful visualisation such as the giraffe project to learn statistics.

I have never used the {RTutor} package but I’m assuming it has a lot of similarities with the {learnr} package as indicated in this blog post.

The {learnr} package is very nice but it has a major problem, the learners need to have their own and unique shiny session. To run a .Rmd file using the {learnr} package, this Rmarkdown has to be deployed on a shiny server and I currently know only two solutions to host a shiny app:

1. With RStudio’s shinyapps.io

This option is super easy and fast to deploy a shiny app and has a free option to deploy 5 shiny apps (that I currently use for my {learnr} tutorials). However, this free option also only includes 5 users in the same time. This is great for the test of specific shiny apps but for parallel learning, it is definitely not enough.

There is the possibility to increase the number of parallel users but it is not free I’m afraid.

2. With a cloud instance using shiny server

The second solution involves creating a cloud instance on AWS or DigitalOcean for example and installing the shiny server to host the Rmarkdown with {learnr}. This solution involves some patience, a bit of knowledge in shell coding and is basically not free (some providers give a free tiers but only for a limited period of time). About the scalability of these solutions, it is apparently possible to scale it to multiple learners in parallel, but I never used them for this purpose so I can’t tell more about how to do it and how many parallel users can use the shiny app.

From what I know, there are two solutions to run a shiny app online which can scale up more than 5 users in the same time and unfortunately none of them are completely free (however I need to explore this AWS free tier solution).

I’m sure that there are alternative solutions and hacks that I am not aware of. For example AWS has so many different services that are a mystery to me. Would it be possible to set a shiny app in an AWS ECS container or to create a lambda with a R environment? My knowledge in AWS competitors such as DigitalOcean, Microsoft Azure or Google Cloud is not good enough to suggest alternative free awesome solutions.

Scale Docker containers with Binder

I recently came across the post of by Florencia d’Andrea explaining how to create an interactive tutorial with Binder, a free service which creates a scalable docker R environment attached to a github/gitlab repository. According to binder, the limit is 100 users simultaneously with is perfect for teaching!

In fact, I was already aware of online tutorial using this setup without knowing how they worked:

By following Florencia’s it is possible to create an interactive R tutorial for free very easily! The procedure described by Florencia and the three interactive tutorials examples as well as mine, are using the framework developed by Ines Montani called Juniper which will make the interface between the Binder docker R environment back end and the tutorial front end. Speaking of front end, Ines is providing a very fancy template using node.js and being deployed with Gatsby. At this point I’m throwing computer science jargon but my understanding of them is very limited. The most important is that it is working very well!

It’s not a perfect solution, see this blog post describing pros and cons for this solution, however it is working and for free.

Interactive {blogdown} using ThebeLab’s Framework

Even if Juniper’s framework is amazing, the content published is based on markdown files. I have nothing against markdown files but I do love Rmarkdown and I really missed them while publishing the tutorials. For this reason I googled “blogdown” + “binder” and found two very interesting discussions:

After being in contact with Achintya and by seeing Christophe’s code, it is possible to identify the essential component to make magic happened:

  1. The blogdown theme or the .Rmd file need to include a code linking it to the repository connected to the binder docker R environment and to the package thebelab which is interacting between both.

In Christophe’s code, this html code is included directly in the .Rmd file:

<!-- Some stuff from thebelab required for the magic -->
<!-- Configure and load Thebe !-->
<script type="text/x-thebe-config">
  {
    requestKernel: true,
    binderOptions: {
      repo: 'github_username/github_reponame,
    },
    kernelOptions: {
      name: "R",
      kernelName: "ir",
    },
  }
</script>

<!-- script for thebelab -->
<script src="https://unpkg.com/thebelab@latest/lib/index.js"></script>

Whereas for Achintya’s blogdown, the following code is included in a specific file ./themes/hugo-lithium/layouts/partials/head_custom.html:

<!-- Configure and load Thebe !-->
<script type="text/x-thebe-config">
    {
        bootstrap: false,
        requestKernel: true,
        binderOptions: {
            repo: 'github_username/github_reponame,
            ref: 'master',
            repoProvider: 'github',
        },
        kernelOptions: {
            name: 'ir',
        }
    }
</script>
<script src="https://unpkg.com/thebelab@0.4.0/lib/index.js"></script>
  1. Both document are including a button to activate the code.

In Christophe’s code the button code and its action on the bootstrapThebe function are directly included in the Rmd file:

# ad a button
htmltools::tags$button(
  id = "activateButton",
  style="width: 100px; height: 50px; font-size: 1.5em;", 
  "Activate"
)

# js chunk
// thebelab js script
var bootstrapThebe = function() {
    thebelab.bootstrap();
}
document.querySelector("#activateButton").addEventListener('click', bootstrapThebe)

For Achintya’s blogdown, the code to create the button is included in a specific file ./themes/hugo-lithium/layouts/shortcodes/code.html and the code to trigger the bootstrapThebe is included in a specific file ./themes/hugo-lithium/layouts/partials/code.html. But to link these html files with the Rmd, each blogdown blog post have to include the following code:

knitr::opts_chunk$set(collapse = TRUE, 
                      attr.source="data-executable='true'",
                      eval = FALSE)

Next steps

For the moment, thanks to Achintya and Christophe’s work, I have a blog test will 2 code chunks that are interactive. The next move will be to convert my Juniper-mardown-node.js tutorial to a thebelab –rmarkdown-blogdown.

Another interesting part would be to integrate a code evaluation system like {gradethis} for example. I’m also wondering if {learnr} would work as well!

Damien Dupré
Damien Dupré
Assistant Professor of Business Research Methods

My research interests relies on time-series analyses of psychological and physiological measures.