# Set chunk options knitr::opts_chunk$set(echo = FALSE) # Get packages suppressPackageStartupMessages(library(tidyverse)) suppressPackageStartupMessages(library(learnr)) suppressPackageStartupMessages(library(pacman)) suppressPackageStartupMessages(library(shiny)) # Character vector of tidyverse package names (and try to protect from rogue # characters in package name; happened with readxl) tidy_pkgs <- tidyverse_packages() %>% # calls character vector str_replace("\n", "") %>% # remove newline str_replace(">=", "") %>% # remove greater than or equal to str_replace("[:punct:]", "") # remove punctuation # Install and load full set of tidyverse packages # (character.only to read elements of character vector, not object name) p_load(char = tidy_pkgs, character.only = TRUE) # Tibble where each row is a package-function combination tidy_funs <- tidy_pkgs %>% enframe(name = NULL, value = "package") %>% mutate(functions = map(package, ~p_functions(.x, character.only = TRUE))) %>% unnest()
Can you select the correct package for the named tidyverse function?
# This chunk contains a Shiny action button # A click will generate a new question actionButton("goButton", "Get Question")
# This chunk attempts to builds the text output that can be passed later to the # quiz() and answer() functions # Generate a random seed value based on current system time # This will be used in the reactive events below seed <- eventReactive( input$goButton, { seed_temp <- as.numeric(Sys.time()) return(seed_temp) } ) # Get function name for subject of question fun_name <- eventReactive( input$goButton, { seed_val <- seed() set.seed(seed_val) # user-selected value is seed value fun_sample <- sample_n(tidy_funs, 1) # random row from package-functions tibble fun_name <- select(fun_sample, functions) %>% pull() # just the function name return(fun_name) } ) output$fun_name_out <- renderText({ paste0("The function `", fun_name(), "` is from which tidyverse package?") }) # Get correct answer ans_correct <- eventReactive( input$goButton, { seed_val <- seed() set.seed(seed_val) # same seed value as above fun_sample <- sample_n(tidy_funs, 1) # same row as for fun_name as above ans_correct <- select(fun_sample, package) %>% pull() # now take package name return(ans_correct) } ) output$ans_correct_out <- renderText({ paste0("{", ans_correct(), "}") }) # Get wrong answer 1 of 3 ans_wrong1 <- eventReactive( input$goButton, { # Recreate ans_correct so we don't set it as a wrong answer as well seed_val <- seed() set.seed(seed_val) fun_sample <- sample_n(tidy_funs, 1) fun_name <- select(fun_sample, functions) %>% pull() ans_correct <- select(fun_sample, package) %>% pull() # Also get packages that have a function with the same name as ans_correct # so we don't see these as a wrong answer as well dup_lookup <- filter(tidy_funs, functions == fun_name) %>% pull(package) # Slightly alter the seed to generate a wrong answer set.seed(seed_val + 1) ans_wrong1 <- tidy_funs %>% distinct(package) %>% # get unique packages filter(!package %in% c(dup_lookup)) %>% # ignore packages with ans_correct sample_n(1) %>% # choose a remaining package name at random pull() # to character return(ans_wrong1) } ) output$ans_wrong1_out <- renderText({ paste0("{", ans_wrong1(), "}") }) # Get wrong answer 2 of 3 # Code as for wrong answer 1, but seed different ans_wrong2 <- eventReactive( input$goButton, { # Recreate ans_correct so we don't set it as a wrong answer as well seed_val <- seed() set.seed(seed_val) fun_sample <- sample_n(tidy_funs, 1) fun_name <- select(fun_sample, functions) %>% pull() ans_correct <- fun_sample %>% select(package) %>% pull() # Also get packages that have a function with the same name as ans_correct # so we don't see these as a wrong answer as well dup_lookup <- filter(tidy_funs, functions == fun_name) %>% pull(package) # Slightly alter the seed to generate a wrong answer set.seed(seed_val + 2) # needs to be a different seed to ans_wrong1 wrong1 <- ans_wrong1() ans_wrong2 <- tidy_funs %>% distinct(package) %>% filter(!package %in% c(dup_lookup, wrong1)) %>% # also exclude pre-selected wrong answer sample_n(1) %>% pull() return(ans_wrong2) } ) output$ans_wrong2_out <- renderText({ paste0("{", ans_wrong2(), "}") }) # Get wrong answer 3 of 3 # Code as for wrong answers 1 and 2 above, but seed different ans_wrong3 <- eventReactive( input$goButton, { # Recreate ans_correct so we don't set it as a wrong answer as well seed_val <- seed() set.seed(seed_val) fun_sample <- sample_n(tidy_funs, 1) fun_name <- select(fun_sample, functions) %>% pull() ans_correct <- fun_sample %>% select(package) %>% pull() # Also get packages that have a function with the same name as ans_correct # so we don't see these as a wrong answer as well dup_lookup <- filter(tidy_funs, functions == fun_name) %>% pull(package) # Slightly alter the seed to generate a wrong answer set.seed(seed_val + 3) # needs to be a different seed to ans_wrong1 wrong1 <- ans_wrong1() wrong2 <- ans_wrong2() ans_wrong3 <- tidy_funs %>% distinct(package) %>% filter(!package %in% c(dup_lookup, wrong1, wrong2)) %>% # also exclude pre-selected wrong answer sample_n(1) %>% pull() return(ans_wrong3) } ) output$ans_wrong3_out <- renderText({ paste0("{", ans_wrong3(), "}") })
quiz( caption = "Question ", question( text = as.character(textOutput("fun_name_out")), answer(as.character(textOutput("ans_correct_out")), correct = TRUE), answer(as.character(textOutput("ans_wrong1_out"))), answer(as.character(textOutput("ans_wrong2_out"))), answer(as.character(textOutput("ans_wrong3_out"))), random_answer_order = TRUE ) )
Made with {learnr}, the tidyverse and {pacman}.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.