--- title: "Writing Interactive Tutorials" output: learnr::tutorial runtime: shiny_prerendered --- ```{r setup, include=FALSE} library(learnr) library(shiny) library(mdsint) library(ggformula) library(mosaic) library(mosaicModel) knitr::opts_chunk$set(echo = FALSE) ``` ## Introduction This document is a tutorial about writing interactive tutorials using the RStudio `learnr` system. You are looking at this document in either of two different ways: 1. As a plain-text file containing the programming elements that go into a tutorial, or 2. Served up as a rendered tutorial with interactive components. This is what you are looking at if you see a nicely formatted document with headers, a table of contents, etc. Ordinarily, a student works with a tutorial in form (2). But for this tutorial you're going to be changing the programming elements in the plain-text file, then *compiling* them to interactive HTML. ## What goes in a tutorial? Tutorials can contain **static narrative** of any sort; anything that you might include in any Rmd document: paragraphs, bullet lists, images, equations, R commands, output from R commands (including graphics), and so on. This is called "static narative" because the student can read it but not otherwise interact with it or change it. In addition to static narrative, tutorials often contain three forms of interactive content: 1. **Questions**, in which the student is able to select an answer. 2. **Exercises**, in which the student writes or modifies R commands in a "command window". 3. **Shiny apps**, which provide interactivity via a graphical-user-interface. ## Narrative These days it seems obvious that moderate exercise is good for your health. For instance, a standard recommendation is that everyone get at least 150 minutes of exercise per week. The benefits of exercise have not always been recognized. One of the first studies to explore the relationship between physical activity and health was a study by epidemiologist [Jerry Morris](https://en.wikipedia.org/wiki/Jerry_Morris) in London in the late 1940s and 1950s. Morris examined health records on about 25,000 London transport workers -- bus drivers and conductors. He was looking in particular to explain the incidence of coronary artery disease. Coronary artery disease affects the blood vessels that supply the heart with oxygen and nutrition. The coronary arteries can become restricted or even completely blocked, reducing oxygen flow and potentially killing heart tissue. The disease is chronic, meaning that it exists, potentially unnoticed, in the background over an extended period of time. But the manifestation of the disease can be very sudden, in the form of a heart attack. In the 1950s, fatality from heart attacks was very high. The data table `Bus_workers` contains the ages and job types of individual London bus workers in 1949. It also reports whether the individual had a heart attack during a one-year interval starting in 1949, and follow-up over three years after the attack to track whether the victim died. ## A multiple-choice question How many of the workers had a heart attack during the one-year period starting in 1949? Here's a command to do the counting: ```{r echo = TRUE} statPREP::counts( ~ event, data = Bus_workers) ``` ```{r Q1} question("Based on this set of counts, what *proportion* of bus workers had a heart attack in the one-year interval?", answer("About one in ten, that is, 10% per year"), answer("About one in one-hundred, that is, 1% per year"), answer("About one in two-hundred fifty, that is, 0.004% per year", correct = TRUE), answer("About one in five-hundred, that is, 0.002% per year") ) ``` ## An R command window In the previous section, you saw that `r sum(Bus_workers$event == "attack")` of the bus workers had a heart attack during the year of the study, and `r sum(Bus_workers$event == "none")` did not. The proportion of workers who had an attack is the number of workers who had an attack divided by the total number of workers. Use the following command box to calculate the exact proportion. ```{r overall_prop, exercise = TRUE, echo = FALSE} ``` It can be much easier to calculate such proportions with software. But there are many different sorts of proportions, and it's important to know which one you want. 1. A simple proportion: How many of the workers had a heart attack? ```{r echo = FALSE} statPREP::counts(~ event, data = Bus_workers, format = "proportion") ``` 2. A joint proportion, e.g. what fraction of the workers were conductors who had a heart attack? ```{r echo = FALSE} statPREP::counts(~ event + job, data = Bus_workers, format = "proportion") ``` Notice in the above that the four numbers in the table add up to 3. That's because every one of the people in `Bus_workers` falls into one of the four categories listed in the table. 4. A conditional proportion, e.g. of the conductors, what fraction had a heart attack? ```{r echo = FALSE} statPREP::counts( ~ event | job, data = Bus_workers, format = "proportion") ``` Keep in mind that it's also possible to ask the question the other way: of the people who had heart attacks, what fraction were conductors? Note that rather than all four numbers adding to one, the numbers in *each column* add to one. The column represents the sub-group (e.g. "of the people who had heart attacks"). Each of the people in this sub-group either had a heart attack or not: those two numbers add up to 1. EXERCISE: Use the following command box to calculate this conditional proportion: of the people who had heart attacks, what fraction were bus drivers? You will have to replace the `..formula..` with an actual formula. Some possibilities to consider: - `~ event` - `~ job` - `~ event + job` - `~ job + event` - `~ job | event` - `~ event | job` ```{r calc_prop, exercise = TRUE, echo = FALSE} statPREP::counts( ..formula.. , data = Bus_workers, format = "proportion") ``` ## Exercise and health The question that Morris wanted to explore was whether the incidence of heart attacks is lower in people who get mild exercise than in people who don't exercise. What's this got to do with bus drivers and conductors? Bus drivers spend almost all their work time sitting. Conductors, on the other hand, are moving around collecting tickets. On the London double-decker busses, this also means going up and down the stairs many times a day. So bus drivers are relatively sedentary compared to bus conductors. QUESTION: Figure out which kind of table will produce the two proportions that Morris wanted to compare. ## Age is almost always a factor Morris was interested in whether exercise is associated with lower heart attack risk. But there's another factor that everybody knew was associated with increased risk: age. Older people are more likely to have heart attacks than younger people. Perhaps the reason behind conductors having lower heart-attack rates is that conductors are, on average, younger than bus drivers. (NOTE IN DRAFT: Add something about age adjustment here.) The following interactive graphic uses the Morris data to fit a model of risk of heart attack versus age. By brushing (click and drag the cursor), you can choose a subset of ages for which to fit the model. (The faint line shows the model for *all* the Morris data.) ```{r child=system.file("bus_workers_app.Rmd", package = "mdsint")} ``` ## Creating a tutorial from scratch You can create a new tutorial by selecting New File/R Markdown then choose "From Template" and, when the list of templates appears, choose "Interactive Tutorial." You will be asked to provide a name for the tutorial. This will become the name of a directory that RStudio will create for your tutorial. The Rmd file you will edit will be in that directory. Some tips: - DO NOT include any spaces or punctuation characters (other than `_`) in the directory name. - Be active in setting the "Location" of this new directory. The default location might not be suitable. ## Deploying your tutorial Presumably, you are writing a tutorial so that your students can use it. In order for students to access your tutorial from a web browser, you need to *deploy* the tutorial to a server. We'll cover how to do this in another webinar. In the meanwhile, if you have a tutorial that you want to deploy, contact Danny Kaplan (`kaplan@macalester.edu`). ## Logging student activity and checking answers In a later tutorial, we'll show you how to log and score student answers and how to provide interactive corrective feedback to exercise chunks.