suppressPackageStartupMessages({
  # # for Shiny Server
  # learnr.dashboard::set_lib_paths("/home/siebrenf/miniconda3/envs/learnr/lib/R/library")

  # packages
  library(learnr)     # 0.10.1.9006 (github)
  library(gradethis)  # 0.1.0.9004  (github)
  library(testthat)   # 3.0.0 
  library(tidyverse)  # 1.3.0
  #library(ggplot2)    # 3.3.2

  # configuration
  options("tutorial.storage"="local")  # save progress in ~/.local/share/R/ see https://bit.ly/3oNP3kF
  knitr::opts_chunk$set(echo = FALSE)
  gradethis::gradethis_setup()
})
session$onSessionEnded(stopApp)

isolate({
  # obtain the session id
  # source 1: https://shiny.rstudio.com/reference/shiny/latest/session.html
  # source 2: https://stackoverflow.com/questions/18900955/get-environment-identifier-in-r
  session_id <- sub('<environment: (.*)>', '\\1', capture.output(session$userData))

  # # send the session ID to the log (indicates the tutorial is loaded)
  # write(paste0("Session ID: ", session_id), stderr())

  # send the session ID to the javascript chunk
  session$sendCustomMessage("session_id", session_id)
})

# stop the tutorial when "input[[session_id]]" is updated
observeEvent(input[[session_id]], ignoreNULL=T, {
  write(paste0("\nTutorial terminated due to inactivity.\nRestart to continue where you left off!\n"), stderr())
  stopApp()
})

```{js timeout2} // This chunk stops the tutorial if it has been idle for too long

// Situation: We need to stop inactive tutorials to prevent the server from grinding to a halt. // Problem: refreshing the tutorial and closing the browser send the same signal to shiny. // since we cannot distinguish the two, this signal cannot be used to stop the tutorial. // Solution: Use a timeout system. // Method: this chunk will update shiny variable "input[[session_id]]" // when the session has been running idle for longer than "timeoutSec" seconds. // This signal is then be used by Shiny (server-side) to stop the session.

// source1: https://community.rstudio.com/t/keeping-track-of-idle-time-during-app-usage/1735 // source2: https://bookdown.org/yihui/rmarkdown/language-engines.html#javascript-and-css $(function() { var timeoutSec = 5*60; var idleTimer;

// receive this session's ID Shiny.addCustomMessageHandler("session_id", function(s_id) { session_id = s_id; // assigns the variable globally });

// assign session ID as reactive variable "input[[session_id]]" function onTimeout() { alert("Tutorial stopped due to inactivity.\nRestart to continue where you left off!") Shiny.setInputValue(session_id, "TRUE"); }

function startIdleTimer() { if (idleTimer) clearTimeout(idleTimer); idleTimer = setTimeout(onTimeout, timeoutSec * 1000); }

$(document).on('shiny:message shiny:inputchanged', startIdleTimer);

})();

```r
# log the first time a user starts this tutorial.

tutorial = "test"
log_path = "/scratch/fg_log"  # make this dir and set 777 permissions!

if (file.access(log_path, 7)[[1]] == 0 ){
  date = Sys.Date()
  user = basename(path.expand("~"))
  log_name = paste0(tutorial, "_", user, "_", date)
  log_file = file.path(log_path, log_name)

  logs = list.files(log_path)  # all currently existing logs
  substring = paste0(tutorial, "_", user)  # date is unimportant
  log_exists = any(lapply(logs, startsWith, substring) == TRUE)
  if (!log_exists){
    invisible(file.create(log_file))
    system(paste0("chmod 777 ", log_file))
  }
}

Embedding

local image:

Typo and Dorianne Gray

online image:

Data science cycle

Some math:

$a^2 + b^2 = c^2$.

single line code:

ls()

multi line code:

ls()

ls again: ls()

A video:

{width="90%"}

Exercises

default exercise code block:


exercise code block, more lines, and output is pre-evaluated:

head(mtcars)

Exercise with Hint

Here's an exercise where the chunk is pre-evaulated via the exercise.eval option (so the user can see the default output we'd like them to customize). We also add a "hint" to the correct solution via the chunk immediate below labeled print-limit-hint.

Modify the following code to limit the number of rows printed to 5:

mtcars
head(mtcars)

multiple hints

1+1
"it's 2"
2

exercise with a text hint

what is the 1st letter of the alphabet


only 1 text hint possible

**Hint:** It's `a`.

gradethis code checking

1+1
grade_result(
  pass_if(~identical(.result, 2))
)

adds a random remark when submitting

custom code checking (setup chunk species checking method)

You can use the count function to count the number of observations in each level of a categorical variable.

How many automatic and how many manual transmission cars are in the data?


mtcars %>%
  count(am)
"Great job!"

Quiz

You can include any number of single or multiple choice questions as a quiz. Use the question function to define a question and the quiz function for grouping multiple questions together.

Some questions to verify that you understand the purposes of various base and recommended R packages:

quiz(
  question("Which package contains functions for installing other R packages?",
    answer("base"),
    answer("tools"),
    answer("utils", correct = TRUE),
    answer("codetools")
  ),
  question("Which of the R packages listed below are used to create plots?",
    answer("lattice", correct = TRUE),
    answer("tools"),
    answer("stats"),
    answer("grid", correct = TRUE)
  )
)

question with retry ON

question(
  "Which of the following is a numerical variable?",
  answer("zip code", message = "Zip code is recoded using numbers, but it's not a numerical variable."),
  answer("height"),
  answer("handedness", correct = TRUE),
  allow_retry = TRUE,
  correct = "Fantastico!"
)

Shiny

sliderInput(
  "binwidth", 
  "Binwidth:", 
  min = 1, max = 30, value = 3
  )
plotOutput("hist")
output$hist <- renderPlot({
  ggplot(data = mtcars, aes(x = mpg)) +
    geom_histogram(binwidth = input$binwidth) +
    labs(
      x = "Miles per gallon",
      y = "Frequency",
      title = "Distribution of MPG"
    )
})

```{js print2pdf1, context="server"} $(document).on('shiny:inputchanged', function(event) { if (event.name === 'print2pdf') { window.print(); } });

```r
actionButton("print2pdf", "Print page", style="opacity: .7; color: #000;")


vanheeringen-lab/learnr.proto documentation built on March 1, 2021, 11:10 p.m.