Structure of an .Rmd-file
The .Rmd is the main file, where all the information about the exercise is contained. It follows a basic structure, with four sections, “Data Generation”, “Question”, “Solution” and “Meta-information”. Their purpose will be described in detail in the following sections.
An empty template containing only the necessary structure can be downloaded here:
After downloading the template, please remove every instance of “eval = FALSE” from the knitr-tags
. This tag is necessary to provide such an empty template for download, but should not be used for creating the exercises!
Basic Structure
Data Generation (code chunk)
Question
Solution
Meta-information
The first section Data Generation, is marked by a code chunk, which is different from the other three sections.
```{r, eval=TRUE, echo=FALSE}
# code is placed here, evaluated, but not echoed in the final document
```
Inside the curly braces {}
it needs to be specified that the following code is written in R. In addition, so called knitr-tags
can be used to alter the appearance of the code and its output within the code chunk. For a detailed overview of knitr-tags
see this website here. A brief overview can be found here in the section about knitr-tags
.
The other three sections are marked as follows
Question========
text is written here.
Solution========
more text is written here.
Meta-information ================
even more text here.
Data Generation
In this section of the .Rmd-file, the answer options for single/multiple choice questions, solutions, the types of questions, explanations and tolerances for solutions are created and stored in list objects for later. In addition there are many additional possibilities, like sampling data, creating graphs, importing pictures etc. which are described on the following page: Add-ons
Description of the lists
The five necessary lists are answers
, solutions
, types
, explanations
and tolerances
, which all have the same length, which is equal to the number of questions in the exercise. For example, in an exam with 5 multiple choice questions, the length of the lists is 5.
Depending on the type and simplicity of the question, some of the lists might not be of equal length, however
The list answers
contains the answer options for single choice/multiple choice questions, not the questions itself. The actual questions are written down in the section “Question”. For numeric and string questions, this list contains placeholders ""
, since no answer options are given. More on the types of questions see below.
The list solutions
contains the solutions for all the questions. For numeric questions, that is a number, (e.g: 123
), for string questions a string like "hello world"
is expected. The solution for single & multiple choiche questions is a boolean vector containing TRUE/FALSE
. For each answer option, one instance of TRUE
or FALSE
is needed. For example, a single choice question with 5 answer options, where one option (in this case the second answer option) is correct, would have a solution vector like this:
c(FALSE, TRUE, FALSE, FALSE, FALSE)
The list types
specifies the type of question for each individual question. Possible values are
numeric (“num”)
string (“string”)
single choice (“schoice”)
multiple choice (“mchoice”)
There are other options avaible, also depending on the output type, see the official R/exams
documentation for more information.
The optional list explanations
contains the feedback that is shown. This can be the complete solutions (it should be then formatted as a list) or additional information like the seed, that was used to create this exercise, session info, etc., which can be written in the “Solution” section. See the Solution section for more details.
The list tolerances
is only necessary for numeric questions, where it is desired to have an interval, in which the solution is accepted as correct, even though the numbers are not perfectly equal. This is important for accommodating rounding differences.
Proceed with caution when random generating numbers and setting an (absolute) tolerance interval, which is too narrow, then the true solution could lie outside of the tolerance interval.
Creating the lists
They are initialized as empty lists, which are later filled with the desired information via sub-setting. See Creation of the .Rmd-file for more details.
<- list()
answers <- list()
solutions <- list()
types <- list()
explanations <- list() tolerances
Question
In this section, all the questions, that should be included in the exam, are written down. This is done in natural language, however bits of code (including R objects), graphs, data, etc. can be included. See more here
Additonal text, like instructions, hints, context, etc. is also written down in this section.
Questions with answer fields
The answer fields mark the place were the answer input should be placed, for example in a moodle quiz, the place where the empty answer box is placed.
Answer fields are marked by ##ANSWERi##
where i is the number of the question, starting with 1.
Numeric question: How many continents are there? ##ANSWER1##
In this case, the answer field is a place-holder, nothing will be displayed, which equals an empty answer field in moodle.
For single/multiple choice questions, ##ANSWERi##
represents the answer options.
Single choice question: Is Vienna the capital of Austria? ##ANSWER2##
With the correct set-up, this will display yes/no
instead of the answer field. In moodle this is a drop-down menu with the two answer options.
Multiple choice question with text components as answer options: The number 3 is ##ANSWER3##
1.
Possible answer options are “greater than”, “smaller than”, “equal to”, which would be displayed instead of the answer field. In moodle all answer options are shown as tickable boxes.
For more examples, see the section “Basic Examples” here and the “Advanced Examples here.
The function answerlist()
from R/exams
package converts the answer options, which are stored in the list object answers
into the necessary format. Additionally, the placeholders needed for numeric/string questions in the answers
list are automatically added into the list in this code chunk.
for (x in 1:length(types)) {
if (types[x] %in% c("num", "string")) {
<- ""
answers[x]
}
}
answerlist(unlist(answers), markup = "markdown")
Solution
The section “Solution” can be used to provide solutions in the form of explanations. It does not create the solutions to the questions and nor is it responsible for assessing/grading questions. Instead it can be used as a reference to review questions or provide feedback. This type of information is created in this section.
The solutions
list contains the actual solutions to the questions, which are used for deeming an answer correct/incorrect, however these are not directly displayed in this section.
The explanations
list holds any information that can be possibly given as feedback. This can, but does not have to, include the actual solutions, depending on the type of exam one is aiming for. This list is optional, general feedback can be normally written as text in this section, see more details on the actual solutions as feedback and other types of explanations below.
Actual Solutions as explanations
The correct solutions to the questions can be displayed in the appropriate format in the generated output.
Some solutions need to be converted to a more understandable format before being displayed. The solutions to schoice/mchoice questions are stored as TRUE/FALSE
vectors and in the following code chunk they are converted to “True” and “False” strings, which are then displayed as explanations to the schoice and mchoice questions.
for (x in 1:length(solutions)) {
if (types[x] %in% c("schoice", "mchoice")) {
<- solutions[x] |> lapply(function(x) ifelse(x, "True", "False"))
explanations[x] else {
} <- solutions[x]
explanations[x]
} }
Then the function answerlist()
from R/exams
processes the explanations
list to adjust it to the format needed for conversion of the .Rmd-file to the desired output.
answerlist(unlist(explanations), markup = "markdown")
Other types of explanations
When the desired feedback is any type of text, like in-depth explanations or providing more context, or more technical details like calculation steps, the explanations
list is not needed. It can simple written as normal text in the .Rmd file under the “Solution” section.
Examples of feedback:
The correct answer is 7, because there are seven recognized continents on Earth: Africa, Antarctica, Asia, Europe, North America, Oceania (or Australia), and South America.
The correct answers are "A" and "C."
Option A is correct because..., and Option C is correct because... Option B, however, is incorrect because .....
In some cases it can be useful to document the seed used, for example when randomly generating numbers or doing any kind of sampling. Providing this information in the “Solution” section to either students or oneself, when for example reviewing questions, can ensure reproducibility.
See the page about add-ons for more information on how to dynamically display R objects (like seeds) in the exam.
Some necessary adjustments for conversion
The following code chunk, which is labelled meta
in the template, converts the solutions of single/multiple choice questions into the necessary 1/0
format. In addition, the second part changes NULL
elements in the tolerances
list to 0, in order to avoid an error during the conversion process.
# Convert the format of single/multiple choice from T/F to 1/0
for (x in 1:length(solutions)) {
if (types[x] %in% c("schoice", "mchoice")) {
<- solutions[x] |>
solutions[x] unlist() |>
mchoice2string()
}
}
# Set all undefined tolerances to a default value
for (x in 1:length(solutions)) {
if (tolerances[x] |> unlist() |> is.null()) {
<- 0
tolerances[x]
} }
Meta-information
This section contains all the information necessary for the conversion from an .Rmd-file to the desired output (HTML, Moodle (xml), pdf, …). The conversion process is decribed here
Tag | Description |
---|---|
exname | name for the exam, should be short and informative |
extitle | longer name for the exam, displayed in Moodle |
extype | specification of the type of exam, e.g: “cloze” |
exsolution | solutions to the questions |
extypes | specification of the types of questions used in the exam |
extol | tolerances used for numeric questions |
exshuffle | logical or numeric value, if/how answer options for schoice/mchoice questions should be shuffled |
exversion | version of the exam |
Also see vignette("exams2", package = "exams")
for additional tags and more information.
Exemplary structure of the Meta-information
This is the meta-information of a very simple exam, containing one numeric question, one single choice and one multiple choice question with three answer options, without any automation using the lists and paste()
.
exname: homework_1
extitle: Homework 1: Topic A
extype: cloze
exsolution: 42.1|TRUE|c(FALSE,TRUE, FALSE)
exclozetype: num|schoice|mchoice
extol: 0.5|0|0
exshuffle: TRUE
exversion: v1
Below is an example of how the “meta-information” section could look with some of the R/exams
tags explained above, as well as automatic conversion of the solutions
, types
and tolerances
list to the correct format using paste()
.
Meta-information================
exname: Abcde
extitle: Abcde: topic xyz
extype: cloze`r paste(solutions, collapse = "|")`
exsolution: `r paste(types, collapse = "|")`
exclozetype: `r paste(tolerances, collapse = "|")`
extol:
exshuffle: TRUE exversion: v1