library(tidyverse) library(learnr)
Hello! I know this is going to seem intimidating, but you get the hang of it very quickly. Before going through this document, open up the tutorial Visualization 1A in RStudio and scroll through to see what the layout of a tutorial looks like.
Also, if you are still confused after reading this document, a great way to learn and familiarize yourself is to actually open up a tutorial file ( go into PPBDS.data, click on the "inst" folder, then open up the "tutorials" folder). If you press "run document" or "knit" in the menu bar of the file, you can then see what the code does visually.
As you should have seen in Visualization 1A, the beginning of a tutorial requires providing your name and email. The tutorial is then divided into sections that you see as side panels. Within these sections, there are a series of exercises which could include writing code, writing text, or answering multiple choice questions. At the end of the tutorial, there is a submission section that provides students with instructions to submit their work.
Ex. This is what the top of the Chapter 4 tutorial looks like:
title: "Functions" Tutorial: Id: “04-functions” output: learnr:: tutorial: progressive: true allow_skip: true runtime: shiny_prerendered description: "Chapter 4 tutorial"
This is what it should look like:
library(tidyverse) library(learnr) library(shiny) library(PPBDS.data) knitr::opts_chunk$set(echo = FALSE, message = FALSE) options(tutorial.exercise.timelimit = 60)
Okay, you are all set up. The first question should ask students to give us their name. (This way, when we generate a hash of a student's responses, their name is included in the hash).
You want an r-chunk that looks like this below. (Note: Follow the same steps in #2 for creating an r-chunk!)
Ex.
## Name ``` {r name} question_text( "Student Name:", answer(NULL, correct = TRUE), allow_retry = TRUE, try_again_button = "Modify your answer", incorrect = "Ok" ) ```
After the name section, the second question should be like the one above, but instead asking for an email.
Ex.
##Email ``` {r email} question_text( "Student Email:”, answer(NULL, correct = TRUE), allow_retry = TRUE, try_again_button = "Modify your answer", incorrect = "Ok" ) ```
NOTE: notice how above both r-chunks there is a double hash with text. This causes the text following the hashes to show up as side panels. (this is explained next).
Otherwise....Congrats! You are all done setting up the tutorial. It’s now time to create content.
Tutorials are divided into sections that are seen on the side panel. To create these sections, we include a double hash before the text for it to show up as a side panel. This is also called the Group Title. There should be a direct mapping of these headers to the subpart of the chapter which they cover. (Ex. If there is an “Basic Commands” section within the chapter, you make this into a Group Title (## Basic Commands).
The hashes work like a sizing system. The group title (double hash ##) is the largest. When you want to make a header within that panel you increase the hash count by 1.
Always place a ‘###”’ on the line below of your Group Title (##). This is a bug issue and the computer needs this to function properly.
Ex. ## Basic Commands ###
To create the exercise headers, you use three hashes. Make sure you number your exercises. This makes it easy for students to refer to a specific location when they have a question. ( Ex. "### Exercise 1", "### Exercise 2" and so on )
You want to think about making questions a series of exercises. Designate each step to a specific exercise. Build multi-part questions slowly and always include earlier parts of the answer in later questions.
Rules:
Make them build step by step, one line after the other. Setting up interim results is confusing. Set up chunks are a bad idea. Get rid of all of them!
Never instruct a student to replace an object with a different one with the same name.
Structure:
When you structure your exercises, you want to show the graph/plot (if applicable) that you will end up creating. You show it once before at the start of the section and before the last exercise (as a reminder of what the graph/plot should look like so students do not need to scroll all the way back up).
You should put the code for the graph in the code chunk at the start of the section. Save the code to an object. The name of the object should have a _p suffix. This way, you only have to put the object in the code chunk at the end of the section rather than typing out the code.
of the
Be careful about defining an object in one question (this won't make sense if you haven't read chapter 1) and then assuming that it will be available in subsequent questions. For example, if you ask students to create a function five_flips()
that flips a coin five times, you need to be careful about assuming that that function is around later for students to use. If you need a function like that later, just define, at the start of this new question. Then ask the student to use that.
Use ###
with no text after a question to create a "Continue" button. This allows students to not be overwhelmed with all the questions they need to do. This will cause R not to show students the next set of questions until they have finished the current set and hit Continue. If you want a "Continue" button to appear after the first question in a given section, you must place ###
below AND above the question (for all other questions, just put it below).
Hints allow students to catch up. Every few questions, have a "hint" which shows all the code up till now, and then also a part of the current step.
When you create a hint, you will often need eval=FALSE
within the parentheses in the r-chunk. This is because hints will often include "..." and other symbols which do not run as correct R code. So, we need to tell R not to run it or an error will occur. All code in a tutorial must work unless it has eval=FALSE
as a code chunk option. If you give a hint which is mostly text, use a single hash mark to specify it as a code comment within the hint code chunk. This causes it to print out more nicely.
Ex:
# Note that this is a bit tricky. There are two --- completely separate! --- # meanings of `x` in this problem. First, `x` is the name of a variable in the # `diamonds` dataset which measures the length of each diamond.
By now, you have been exposed briefly to r-chunks (that grey space bove with the green text). These code chunks create the space where the students enter the code within the tutorial.
No spaces around "=" in R code chunk options ( For example, write eval=FALSE
, not eval = FALSE
)
You will generally need to backslashes when using math notation in question_text()
, e.g., $\\tau$
in place of $\tau$
.
The exercise code chunk should not have zero lines. It can be blank, but it must have at least one empty line.
Code chunks for questions must be named ( if you look at the r-chunk above, you will see that the r chunk is named "r gj-2-5-hint" . Don't worry about the naming/numbering, as long as the code chunks don't have duplicate names.
Whenever you create a hint, the name of the r chunk must have the same name as the r chunk exercise but have "-hint" attached to it ( look at a tutorial file and you will understand this better).
If you want to provide an example code chunk, either in the answer block or in the hint, use "..." to indicate a spot which students need to fill in with a variable name or argument value or whatever.
Example:
qscores %>% ggplot(aes(...)) + geom_histogram()
(The question would tell the student to replace ... with hours
in order to construct a histogram)
Format your code nicely. The key is to use only one command per line in pipes and graphics, with proper indentation. Indent plotting commands after ggplot().
Do not provide official learnr answers. There is no need to grade what the students submit. You may sometimes provide answers in a code comment, as a service to others authors working on the tutorial. Use your best judgment.
If you would like to write an open-ended question in which students can type out a text response, use question_text()
.
``` {r name} question_text( "Student Name:", answer(NULL, correct = TRUE), allow_retry = TRUE, try_again_button = "Modify your answer", incorrect = "Ok" ) ```
Use built-in data sets in constructing tutorial questions, or use data sets which you create yourself in the tutorial. Note that several packages from the tidyverse have built in data, although it is worth making sure that they are tibbles rather than data frames. To see all the data sets in the Tidyverse, type library(tidyverse)
first. Then, you can look at these with --- data()
--- and then looking for data sets associated with tidyverse packages. You can also use data sets from PPBDS.data.
The last section/ panel of your tutorial must be the Submit section. This prints out instructions for students to generate a hash of their submissions, enter it, and download an .rds file containing their hash to be uploaded to Canvas. As you can see, Shiny UI elements are incorporated along with the learnrhash
package.
submission_ui
submission_server()
Once you are done writing your tutorial, you need to make sure it works before you submit a Pull Request.
Hit Run Document. This mimics the experience that users will have. This will catch some common errors, like having two code chunks with the same name.
Do a full test, which is an R CMD check. Go to the top right window of RStudio. Click the Build pane and hit the "Check" button (with the green check mark). You will then see a bunch of code and tests running. The most important is to make sure it says "OK" next to “testthat”. You should always run this before submitting a pull request.
Read the error message at the bottom of the Build pane. You want to see "R CMD check succeeded." If not, there is a problem. The error message will often provide a clue as to where in your code the error occurred.
If that error message is not detailed enough, go to the "PPBDS.data.rcheck" folder, which should be located in the same directory as PPBDS.data. This is a folder created by the R CMD check process, and it will delete when the check process succeeds. If the process fails, the .rcheck folder stays around so that you can examine it. The key file in there is testthat.Rout.fail, which should be in the tests directory. It has more details.
The most common source of errors is something wrong with the hint code chuncks, which are not evaluated when you just Run Document. Make sure the eval=FALSE
is set in the code chunk for all hints.
The main question was: How do we incorporate tutorial questions directly into the chapter itself? Allison is the world expert on this topic.
She is concerned about user loads for published Shiny apps - would recommend that we use the basic or higher plan.
She thinks using Desiree's method of embedding one exercise at a time might get unreasonable for a book of our size, but suggested that we could host 12 different ShinyApps corresponding to each chapter, and then link to each chapter in one central location. (Kind of like the combined tutorials app Evelyn created via HMDC.)
How did you decide which exercises were going to be "tutorials" and which would be "exercises"? She wanted the exercises to be incremental, so a lot of the code was already pre-populated. The exercises that were blank built directly off of code that was already shown before, so that students could have an "easy win" by just copying the previous code and tweaking a variable name. Allison thinks that this incremental process is important for beginner R students.
How much memory does the ShinyApp consume? Do you know of any tricks to make learnr tutorials smaller? She recommends that we contact the team at RStudio Education - this is not her area of expertise. Allison says that the RStudio Education team is super eager to hear about learnr use cases, would be happy to talk to us, and would even ask us to write a blog post. She also mentioned that the team would know the most about cutting-edge learnr stuff, including things like a "completion rate" bar that shows students how far they are through a tutorial.
Any tips for remote teaching or learning? Using learnr at all is a big step. Allison also pre-records short versions of her lectures for her students to stream at a later time, and holds smaller discussion sections in class where they do activities.
Allison's #1 Recommendation to remote teachers of R: Having students start out with RStudio Cloud and then transitioning to Desktop. You can set up workspaces so the necessary packages are already loaded and installed, any script is already pre-loaded, and all students need to do is log in. It looks exactly the same as RStudio Desktop except folks don't have to worry about installing R or RStudio. You can push/pull from git in RStudio Cloud as well (link to a Rstudio cloud tutorial/article: https://rstudio.com/resources/webinars/teaching-r-online-with-rstudio-cloud/)
Maybe this is how we should do all hints, so as to avoid the compile error issue.
https://github.com/tinystats/teacups-giraffes-and-statistics
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.