Embedding R/exams Exercises as Forms in R/Markdown or Quarto Documents

#| include: false
library("exams2forms")
set.seed(403)
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "##",
  message = FALSE,
  warning = FALSE,
  echo = TRUE
)

Overview

The package exams2forms provides several building blocks for embedding exercises written with the R package exams (also known as R/exams) in interactive documents or quizzes written with rmarkdown or quarto.

The idea is that the dynamic exercises in R/exams' Rmd (R/Markdown) or Rnw (R/LaTeX) format can also be reused in HTML documents, web pages, or online books. This facilitates their use for self-paced learning and self-assessment without the need for a learning management system etc. (By default the correct answers are obfuscated in the documents so that they are not obvious when inspecting the HTML source code.)

For (summative) assessments the same dynamic exercises could then be exported to different learning management systems or employed in written exams.

All R/exams exercise types are supported:

Many of the ideas as well as the code in the package have been adapted from the webexercises package, authored by Dale Barr and Lisa DeBruine.

First examples

As a quick demonstration for R/exams exercises embedded into an HTML document, the two examples from the First Steps tutorial are included below: The single-choice exercise swisscapital and the numeric exercise deriv, both in three random variations.

#| echo: false
#| results: "asis"
library("exams2forms")
exams2forms(c("swisscapital.Rmd", "deriv.Rmd"), n = 3)

In addition to the question and the interaction element, there are three buttons providing the following functionality.

| Button | Function | |:--------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | | Check the answer and display whether it is correct or not. When clicked, the symbol is toggled and is displayed, which can be clicked to hide the solution again. | | ? | Display the full correct solution explanation. | | | Switch to the next question. |

Inclusion of the solution explanation is optional and the next question button is only displayed if there is more than one random variation of a question. The icons and mouseover text can also be adapted (see below).

To set up a similar standalone file with these two exercises, the exams2webquiz() interface from the exams2forms package can be used:

#| eval: false
library("exams2forms")
exams2webquiz(c("swisscapital.Rmd", "deriv.Rmd"), n = 3)

More elaborate examples

To showcase some more exercise types, the following examples from the R/exams package are used: capitals (multiple-choice), function (string/text), fruit (numeric with table and images), lm2 (cloze containing string, multiple-choice, numeric, and single-choice elements as well as an embedded data file).

#| echo: false
#| results: "asis"
exams2forms(c("capitals.Rmd", "function.Rmd", "fruit.Rmd", "lm2.Rmd"))

Again, the exams2webquiz() function can be used to set up a standalone file based on the same exercises:

#| eval: false
exams2webquiz(c("capitals.Rmd", "function.Rmd", "fruit.Rmd", "lm2.Rmd"))

Building blocks

To accomplish the functionality demonstrated above, the package provides the following contents:

Demo files

While exams2webquiz() is convenient for quickly setting up an HTML document containing certain exercises, further customizations are typicallly needed for more elaborate documents. To demonstrate how this works the exams2forms package provides two demo rmarkdown files which can also be downloaded here:

The first file quiz.Rmd renders a number of different exercises into a quiz using a single exams2forms() call, indicating that the results should be included "asis":

writeLines(paste0("    ", readLines(
  system.file("forms", "quiz.Rmd", package = "exams2forms")
)))

The questions.Rmd file looks similar but contains different sections, each with a single question set up via exams2forms().

Both files can be rendered to HTML via rmarkdown::render() or by clicking the knit button after opening the files in RStudio etc.

Setup and customization

When setting up a more elaborate document or even a full webpage or online book with rmarkdown or quarto, then the simple webquiz() HTML document provided by exams2forms is probably not sufficient. In this case, it is best to take the CSS and Javascript files from the package or download them here:

The files can then be placed in the same folder as the rmarkdown or quarto project. They can also be adapted relatively easily by changing the definitions of colors, icons, text, etc. in the first few lines of each file.

To include the CSS and Javascript in an rmarkown project, the YAML header should include:

output:
  html_document:
    css: webex.css
    includes:
      after_body: webex.js

Similarly, in a quarto project the YAML header or the _quarto.yml file should include:

format:
  html:
    css: webex.css
    include-after-body: webex.js

Standalone interaction forms

While it is not the primary focus of the exams2forms package, it is also possible to directly include interaction forms in documents like in the webexercises package, i.e., without setting up full R/exams exercises. A few simple examples are inlcuded below for numeric, text, single-choice, and multiple-choice interactions (both using drop-down interactions here), respectively.

What is the answer to the ultimate question of life, the universe, and everything? r forms_num(42, width = 10)

Which superhero is the secret identity of Bruce Wayne? r forms_string("Batman", width = 20, usecase = FALSE)

Which of the following villains is not an adversary of Batman? r forms_schoice(c("Bane", "Riddler", "Thanos", "Poison Ivy"), c(FALSE, FALSE, TRUE, FALSE), display = "dropdown")

Which of the following characters are romantic interests of Spider-Man?

r forms_mchoice(c("Mary Jane Watson", "Pepper Potts", "Selina Kyle", "Gwen Stacy"), c(TRUE, FALSE, FALSE, TRUE), display = "dropdown")

The corresponding code snippets included in the inline code chunks are:



Try the exams2forms package in your browser

Any scripts or data that you put into this service are public.

exams2forms documentation built on May 9, 2025, 3 a.m.