Slide 1

Slide 1 text

building and maintaining using the R ecosystem mine-cetinkaya-rundel [email protected] @minebocek 🔗 bit.ly/openintro-useR2021 mine çetinkaya-runde l duke university & rstudio

Slide 2

Slide 2 text

OpenIntro’s mission is to make educational products that are free, transparent, and lower barriers to education. mission 🔗 bit.ly/openintro-useR2021

Slide 3

Slide 3 text

🔗 bit.ly/openintro-useR2021 openintro.org

Slide 4

Slide 4 text

🔗 bit.ly/openintro-useR2021

Slide 5

Slide 5 text

team 🔗 bit.ly/openintro-useR2021

Slide 6

Slide 6 text

books labs tutorials other packages 🔗 bit.ly/openintro-useR2021

Slide 7

Slide 7 text

Preliminary Edition how it started how it’s going 🔗 bit.ly/openintro-useR2021

Slide 8

Slide 8 text

Preliminary Edition First Edition Second Edition First Edition First Edition 🔗 bit.ly/openintro-useR2021

Slide 9

Slide 9 text

๏Applications as motivation ๏Real, recent, relatable datasets ๏Emphasis on data exploration, multivariable relationships, and statistical reasoning ๏Guided practices and worked examples interspersed in text ๏Lots of end of chapter exercises, with solutions to odd numbered questions in the back pedagogy 🔗 bit.ly/openintro-useR2021

Slide 10

Slide 10 text

license 🔗 bit.ly/openintro-useR2021

Slide 11

Slide 11 text

๏HTML textbook freely available ๏PDF also freely available — distributed through LeanPub with a suggested donation (min $0) ๏Paperback available at low cost — cost of printing + minimal royalty that goes back to OpenIntro (US-based nonpro fi t) “business” model 🔗 bit.ly/openintro-useR2021

Slide 12

Slide 12 text

how it started ๏Each chapter its own LaTeX fi le ๏Each fi gure in a folder with associated R code that generates it + how it’s made 🔗 bit.ly/openintro-useR2021

Slide 13

Slide 13 text

how it’s going ๏Each chapter its own Rmd fi le ๏Output to HTML and PDF with the same source code (and lots of customization!) how it’s made 🔗 bit.ly/openintro-useR2021

Slide 14

Slide 14 text

๏Challenge: Convert from LaTeX to R Markdown ๏Step 1: Pandoc magic! conversion # Load packages ---------------------------------------------------------------- library(fs) library(tidyverse) # Convert from tex to md ------------------------------------------------------- tex_to_md <- function(tex_file_name){ # convert md_file_name <- str_replace(tex_file_name, "\\.tex$", ".md") system_call <- paste("pandoc -s" , tex_file_name, "-o", md_file_name) system(system_call) # delete tex file_delete(tex_file_name) } # Convert from md to rmd ------------------------------------------------------- md_to_rmd <- function(md_file_name){ rmd_file_name <- md_file_name %>% str_replace("\\.md$", ".Rmd") file_move( path = md_file_name, new_path = rmd_file_name ) } # Get tex file names ----------------------------------------------------------- tex_file_names <- dir_info(recurse = 2, glob = "*.tex") %>% pull(path) # Convert from .tex to .md ----------------------------------------------------- walk(tex_file_names, tex_to_md) md_file_name <- str_replace(tex_file_name, "\\.tex$", ".md") system_call <- paste("pandoc -s" , tex_file_name, "-o", md_file_name) system(system_call) tex_file_names <- dir_info(recurse = 2, glob = "*.tex") %>% pull(path) walk(tex_file_names, tex_to_md) 🔗 bit.ly/openintro-useR2021

Slide 15

Slide 15 text

conversion ๏ stringr and regular expressions for cleaning custom LaTeX! And when in doubt, add more //s! tex_file_clean <- tex_file %>% str_replace("\\\\qt\\{(.*?)(\n)?(\\s)*(.*?)\\\\label\\{.*?\\}\\}", "\\\\textbf{\\1 \\4}") %>% str_replace_all("begin\\{parts\\}", "begin{enumerate}\n\\\\def\\\\labelenumii{\\\\alph{enumii}.}") %>% str_replace_all("end\\{parts\\}", "end{enumerate}") %>% str_replace_all("\\\\footfullcite", " \\\\citep") %>% str_replace_all("\\.pdf", ".png") ๏ magick::image_convert() to convert PDFs to PNGs ๏ fs::file_delete() to remove fi les no longer needed ๏Challenge: Convert from LaTeX to R Markdown ๏Step 2: Post-processing 🔗 bit.ly/openintro-useR2021

Slide 16

Slide 16 text

custom blocks ๏Challenge: Achieve similar looking custom blocks in HTML and PDF output ๏Solution: Fenced div blocks + Custom blocks chapter of the R Markdown Cookbook 🔗 bit.ly/openintro-useR2021 ::: {.guidedpractice data-latex=""} ::: Rmd .guidedpractice { padding: 1em 1em 1em 4em; margin-top: 30px; margin-bottom: 30px; background: #f8f8f8 5px center/3em no-repeat; border-top: 1px solid #569BBD; /* openintro::COL[1,1] */ border-bottom: 1px solid #569BBD; /* openintro::COL[1,1] */ background-image: url("../images/_icons/guided-practice.png"); background-position: 0.5em 1em; } .guidedpractice:before { content: "Guided practice"; clear: right; display: block; font-weight: bold; font-variant: small-caps; color: #569BBD; } CSS \newenvironment{guidedpractice}{ \vspace{4mm} \begin{mdframedwithfootGPWE} \begin{minipage}[t]{0.10\textwidth} {$\:$ \\ \setkeys{Gin}{width=2.5em,keepaspectratio} \includegraphics{images/_icons/guided-practice.png}} \end{minipage} \hfill \begin{minipage}[t]{0.90\textwidth} \vspace{-2mm} \setlength{\parskip}{1em} \noindent\textbf{\color{oiB}\small\fontfamily{phv} \selectfont{\MakeUppercase{Guided Practice}}} $\:$ \\ \\ } {\end{minipage} \end{mdframedwithfootGPWE} \vspace{4mm} } LaTeX

Slide 17

Slide 17 text

plots ๏Challenge: A consistent and branded look for plots ๏Solution: De fi ne theme_openintro() and rede fi ne ggplot2 defaults 🔗 bit.ly/openintro-useR2021 ggplot2::update_geom_defaults("point", list(color = openintro::IMSCOL["blue","full"], fill = openintro::IMSCOL["blue","full"])) ggplot2::update_geom_defaults("bar", list(fill = openintro::IMSCOL["blue","full"], color = "#FFFFFF")) ggplot2::update_geom_defaults("col", list(fill = openintro::IMSCOL["blue","full"], color = "#FFFFFF")) ggplot2::update_geom_defaults("boxplot", list(color = openintro::IMSCOL["blue","full"])) ggplot2::update_geom_defaults("density", list(color = openintro::IMSCOL["blue","full"])) ggplot2::update_geom_defaults("line", list(color = openintro::IMSCOL["gray", "full"])) ggplot2::update_geom_defaults("smooth", list(color = openintro::IMSCOL["gray", "full"])) ggplot2::update_geom_defaults("dotplot", list(color = openintro::IMSCOL["blue","full"], fill = openintro::IMSCOL["blue","full"]))

Slide 18

Slide 18 text

๏Challenge: ๏ Source code for what’s in the printed book should be publicly available ๏ Source code for full solutions should not be publicly available ๏ Question, full solution, and short answer should all live in the same repo ๏Solution: ๏ Separate repo for exercises: 1 folder per exercise, containing 1 Rmd / question, short answer, full solution ๏ Programmatically generate a single Rmd for exercises for each chapter map(question_paths, read_lines) %>% map_chr(~ paste(.x, collapse = "\n")) %>% paste(collapse = "\n\n") %>% # fix figure path str_replace_all("images/", glue("exercises/images/")) %>% # write out write_lines(out_file_path) questions_odd <- tibble( question_no = 1:length(questions), question_label = questions ) %>% mutate(odd_even = if_else((question_no %% 2) != 0, "odd", "even")) %>% filter(odd_even == "odd") %>% pull(question_label) ๏ Programmatically generate a single Rmd for short solutions of odd numbered exercises for each chapter exercises 🔗 bit.ly/openintro-useR2021

Slide 19

Slide 19 text

books labs tutorials other packages 🔗 bit.ly/openintro-useR2021

Slide 20

Slide 20 text

🔗 bit.ly/openintro-useR2021

Slide 21

Slide 21 text

on: push name: Render Rmd jobs: render: name: Render Rmd runs-on: macOS-latest steps: - uses: actions/checkout@v2 - uses: r-lib/actions/setup-r@v1 - uses: r-lib/actions/setup-pandoc@v1 - uses: Install rmarkdown, remotes, and the local package run: | install.packages("remotes") remotes::install_cran(c("rmarkdown", "tidyverse", "openintro", "infer", "statsr", "GGally", "skimr")) shell: Rscript {0} - name: Render Lab 01 run: Rscript -e 'rmarkdown::render("01_intro_to_r/intro_to_r.Rmd")' … - name: Render Lab 09 run: Rscript -e 'rmarkdown::render("09_multiple_regression/multiple_regression.Rmd")' - name: Commit results run: | git config --local user.email "[email protected]" git config --local user.name "GitHub Actions" git commit -a -m 'Re-build Rmd' || echo "No changes to commit" git push origin || echo "No changes to commit" ๏Challenge: Maintenance ๏Solution: Use GitHub Actions (borrowed from r-lib/actions) to re-render Rmds with each push and PR merge 🔗 bit.ly/openintro-useR2021

Slide 22

Slide 22 text

books labs tutorials other packages 🔗 bit.ly/openintro-useR2021

Slide 23

Slide 23 text

๏Challenge: Keep main text software agnostic, but teach modern statistics! ๏Solution: Supplement with interactive R tutorials developed with learnr 🔗 bit.ly/openintro-useR2021

Slide 24

Slide 24 text

books labs tutorials other packages 🔗 bit.ly/openintro-useR2021

Slide 25

Slide 25 text

🔗 bit.ly/openintro-useR2021

Slide 26

Slide 26 text

๏Challenge: Datasets blow up package size ๏Solution: Break into smaller packages, and bring them along automatically Depends: R (>= 2.10), airports, cherryblossom, usdata + 🔗 bit.ly/openintro-useR2021

Slide 27

Slide 27 text

contributing 🔗 bit.ly/openintro-useR2021

Slide 28

Slide 28 text

๏Open an issue ๏Make a pull request github.com/openintrostat 🔗 bit.ly/openintro-useR2021

Slide 29

Slide 29 text

openintro.org ๏Send feedback ๏Report a typo 🔗 bit.ly/openintro-useR2021

Slide 30

Slide 30 text

openintro.org/teachers/get_involved ๏Datasets: Data hunter ๏Exams: Exam contributor ๏Exercises: ๏ Exercise contributor ๏ MyOpenMath exercise conversion ๏Labs: ๏ Lab solution developer ๏ New software owner ๏ New lab developer ๏Modules: ๏ Module developer ๏ Module editor ๏Translation ๏Your ideas? 🔗 bit.ly/openintro-useR2021

Slide 31

Slide 31 text

thank you! mine-cetinkaya-rundel [email protected] @minebocek mine çetinkaya-runde l duke university & rstudio bit.ly/openintro-useR2021