├── .Rbuildignore ├── .gitattributes ├── .gitignore ├── Intro2R.Rproj ├── LICENSE.md ├── README.md ├── _exercises ├── 00_import_data.qmd ├── 01_dplyr.qmd ├── 02_viz.qmd ├── 02_viz_interactivity.qmd ├── 03_pivot.qmd ├── 04_join.qmd ├── 05_functions_exercise.qmd ├── 06_nest_exercise.Rmd └── answers │ ├── 00_import_answers.qmd │ ├── 01_dplyr_answers.qmd │ ├── 02_viz_ggplot2_answers.qmd │ ├── 02_viz_interactivity_answers.qmd │ ├── 03_pivot_answers.qmd │ ├── 04_join_answers.qmd │ ├── 05_functions_answers.qmd │ └── 06_nest_answers.Rmd ├── _freeze ├── functions │ ├── execute-results │ │ └── html.json │ └── figure-html │ │ ├── unnamed-chunk-2-1.png │ │ ├── unnamed-chunk-2-2.png │ │ └── unnamed-chunk-3-1.png ├── import │ ├── execute-results │ │ └── html.json │ └── figure-html │ │ ├── unnamed-chunk-4-1.png │ │ ├── unnamed-chunk-5-1.png │ │ └── unnamed-chunk-6-1.png ├── interactive │ └── execute-results │ │ └── html.json ├── join │ └── execute-results │ │ └── html.json ├── longer_wider │ ├── execute-results │ │ └── html.json │ └── figure-html │ │ ├── unnamed-chunk-10-1.png │ │ ├── unnamed-chunk-11-1.png │ │ ├── unnamed-chunk-12-1.png │ │ ├── unnamed-chunk-7-1.png │ │ ├── unnamed-chunk-8-1.png │ │ └── unnamed-chunk-9-1.png ├── purrr │ ├── execute-results │ │ └── html.json │ └── figure-html │ │ ├── unnamed-chunk-10-1.png │ │ └── unnamed-chunk-10-2.png ├── regression │ ├── execute-results │ │ └── html.json │ └── figure-html │ │ ├── unnamed-chunk-15-1.png │ │ ├── unnamed-chunk-15-2.png │ │ └── unnamed-chunk-6-1.png ├── site_libs │ ├── Proj4Leaflet-1.0.1 │ │ └── proj4leaflet.js │ ├── bootstrap-grid-3.4.1 │ │ └── bootstrap-grid.min.css │ ├── clipboard │ │ └── clipboard.min.js │ ├── core-js-2.5.3 │ │ ├── LICENSE │ │ ├── package.json │ │ └── shim.min.js │ ├── crosstalk-1.2.0 │ │ ├── css │ │ │ └── crosstalk.min.css │ │ ├── js │ │ │ ├── crosstalk.js │ │ │ ├── crosstalk.js.map │ │ │ ├── crosstalk.min.js │ │ │ └── crosstalk.min.js.map │ │ └── scss │ │ │ └── crosstalk.scss │ ├── datatables-binding-0.28 │ │ └── datatables.js │ ├── datatables-binding-0.31 │ │ └── datatables.js │ ├── datatables-css-0.0.0 │ │ └── datatables-crosstalk.css │ ├── dt-core-bootstrap-1.13.4 │ │ ├── css │ │ │ ├── dataTables.bootstrap.extra.css │ │ │ └── dataTables.bootstrap.min.css │ │ └── js │ │ │ ├── dataTables.bootstrap.min.js │ │ │ └── jquery.dataTables.min.js │ ├── dt-core-bootstrap-1.13.6 │ │ ├── css │ │ │ ├── dataTables.bootstrap.extra.css │ │ │ └── dataTables.bootstrap.min.css │ │ └── js │ │ │ ├── dataTables.bootstrap.min.js │ │ │ └── jquery.dataTables.min.js │ ├── dt-ext-scroller-bootstrap-1.13.4 │ │ ├── css │ │ │ └── scroller.bootstrap.min.css │ │ └── js │ │ │ ├── dataTables.scroller.min.js │ │ │ └── scroller.bootstrap.min.js │ ├── dt-ext-scroller-bootstrap-1.13.6 │ │ ├── css │ │ │ └── scroller.bootstrap.min.css │ │ └── js │ │ │ ├── dataTables.scroller.min.js │ │ │ └── scroller.bootstrap.min.js │ ├── dygraphs-1.1.1 │ │ ├── dygraph-combined-dev.js │ │ ├── dygraph-combined.js │ │ ├── dygraph.css │ │ └── shapes.js │ ├── dygraphs-binding-1.1.1.6 │ │ └── dygraphs.js │ ├── htmlwidgets-1.6.2 │ │ └── htmlwidgets.js │ ├── ionicons-2.0.1 │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.min.css │ │ ├── bootstrap.min.js │ │ ├── font-awesome.min.css │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ ├── ionicons.eot │ │ │ ├── ionicons.svg │ │ │ ├── ionicons.ttf │ │ │ └── ionicons.woff │ │ ├── images │ │ │ ├── markers-matte.png │ │ │ ├── markers-matte@2x.png │ │ │ ├── markers-plain.png │ │ │ ├── markers-shadow.png │ │ │ ├── markers-shadow@2x.png │ │ │ ├── markers-soft.png │ │ │ └── markers-soft@2x.png │ │ ├── ionicons.min.css │ │ ├── leaflet.awesome-markers.css │ │ ├── leaflet.awesome-markers.js │ │ └── leaflet.awesome-markers.min.js │ ├── ionrangeslider-css-2.3.1 │ │ ├── css │ │ │ └── ion.rangeSlider.css │ │ ├── js │ │ │ ├── ion.rangeSlider.js │ │ │ └── ion.rangeSlider.min.js │ │ └── scss │ │ │ ├── _base.scss │ │ │ ├── _mixins.scss │ │ │ └── shiny.scss │ ├── ionrangeslider-javascript-2.3.1 │ │ ├── css │ │ │ └── ion.rangeSlider.css │ │ ├── js │ │ │ ├── ion.rangeSlider.js │ │ │ └── ion.rangeSlider.min.js │ │ └── scss │ │ │ ├── _base.scss │ │ │ ├── _mixins.scss │ │ │ └── shiny.scss │ ├── jquery-3.5.1 │ │ ├── jquery-AUTHORS.txt │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map │ ├── jquery-3.6.0 │ │ ├── jquery-3.6.0.js │ │ ├── jquery-3.6.0.min.js │ │ └── jquery-3.6.0.min.map │ ├── leaflet-1.3.1 │ │ ├── images │ │ │ ├── layers-2x.png │ │ │ ├── layers.png │ │ │ ├── marker-icon-2x.png │ │ │ ├── marker-icon.png │ │ │ └── marker-shadow.png │ │ ├── leaflet.css │ │ └── leaflet.js │ ├── leaflet-binding-2.1.2 │ │ └── leaflet.js │ ├── leaflet-binding-2.2.0 │ │ └── leaflet.js │ ├── leaflet-easybutton-1.3.1 │ │ ├── EasyButton-binding.js │ │ ├── LICENSE │ │ ├── easy-button.css │ │ └── easy-button.js │ ├── leaflet-locationfilter2-0.1.1 │ │ ├── img │ │ │ ├── filter-icon.png │ │ │ ├── move-handle.png │ │ │ └── resize-handle.png │ │ ├── locationfilter-bindings.js │ │ ├── locationfilter.css │ │ └── locationfilter.js │ ├── leafletfix-1.0.0 │ │ └── leafletfix.css │ ├── moment-2.8.4 │ │ ├── moment-timezone-with-data.js │ │ └── moment.js │ ├── moment-fquarter-1.0.0 │ │ └── moment-fquarter.min.js │ ├── moment-timezone-0.2.5 │ │ ├── moment-timezone-with-data.js │ │ └── moment.js │ ├── pagedtable-1.1 │ │ ├── css │ │ │ └── pagedtable.css │ │ └── js │ │ │ └── pagedtable.js │ ├── plotly-binding-4.10.2 │ │ └── plotly.js │ ├── plotly-binding-4.10.3 │ │ └── plotly.js │ ├── plotly-htmlwidgets-css-2.11.1 │ │ └── plotly-htmlwidgets.css │ ├── plotly-main-2.11.1 │ │ └── plotly-latest.min.js │ ├── proj4-2.6.2 │ │ └── proj4.min.js │ ├── react-17.0.0 │ │ ├── AUTHORS │ │ ├── LICENSE.txt │ │ ├── react-dom.min.js │ │ └── react.min.js │ ├── react-18.2.0 │ │ ├── AUTHORS │ │ ├── LICENSE.txt │ │ ├── react-dom.min.js │ │ └── react.min.js │ ├── reactable-0.4.4 │ │ ├── reactable.css │ │ ├── reactable.js │ │ ├── reactable.js.map │ │ ├── reactable.server.js │ │ ├── reactable.server.js.LICENSE.txt │ │ ├── reactable.server.js.map │ │ └── reactable.yaml │ ├── reactable-binding-0.4.4 │ │ └── reactable.js │ ├── reactwidget-1.0.0 │ │ ├── react-tools.js │ │ └── react-tools.js.map │ ├── rstudio_leaflet-1.3.1 │ │ ├── images │ │ │ └── 1px.png │ │ └── rstudio_leaflet.css │ ├── strftime-0.9.2 │ │ └── strftime-min.js │ └── typedarray-0.1 │ │ └── typedarray.min.js ├── tidy_tuesday_itra │ ├── execute-results │ │ └── html.json │ └── figure-html │ │ ├── unnamed-chunk-19-1.png │ │ ├── unnamed-chunk-20-1.png │ │ ├── unnamed-chunk-21-1.png │ │ ├── unnamed-chunk-22-1.png │ │ ├── unnamed-chunk-23-1.png │ │ ├── unnamed-chunk-24-1.png │ │ ├── unnamed-chunk-25-1.png │ │ ├── unnamed-chunk-26-1.svg │ │ ├── unnamed-chunk-27-1.png │ │ └── unnamed-chunk-27-2.png ├── viz │ ├── execute-results │ │ └── html.json │ └── figure-html │ │ ├── patchwork-example-1.png │ │ ├── plot-sleep-labs-1.png │ │ ├── unnamed-chunk-10-1.png │ │ ├── unnamed-chunk-11-1.png │ │ ├── unnamed-chunk-12-1.png │ │ ├── unnamed-chunk-13-1.png │ │ ├── unnamed-chunk-14-1.png │ │ ├── unnamed-chunk-15-1.png │ │ ├── unnamed-chunk-16-1.png │ │ ├── unnamed-chunk-17-1.png │ │ ├── unnamed-chunk-18-1.png │ │ ├── unnamed-chunk-19-1.png │ │ ├── unnamed-chunk-2-1.png │ │ ├── unnamed-chunk-20-1.png │ │ ├── unnamed-chunk-21-1.png │ │ ├── unnamed-chunk-22-1.png │ │ ├── unnamed-chunk-23-1.png │ │ ├── unnamed-chunk-24-1.png │ │ ├── unnamed-chunk-25-1.png │ │ ├── unnamed-chunk-27-1.png │ │ ├── unnamed-chunk-28-1.png │ │ ├── unnamed-chunk-29-1.png │ │ ├── unnamed-chunk-30-1.png │ │ ├── unnamed-chunk-4-1.png │ │ ├── unnamed-chunk-5-1.png │ │ ├── unnamed-chunk-6-1.png │ │ ├── unnamed-chunk-7-1.png │ │ ├── unnamed-chunk-8-1.png │ │ └── unnamed-chunk-9-1.png ├── widgets │ └── execute-results │ │ └── html.json └── wrangle │ └── execute-results │ └── html.json ├── _publish.yml ├── _quarto.yml ├── _redirects ├── about.qmd ├── ai.qmd ├── data-sources-for-regression-analysis.qmd ├── data ├── 538_favorability_popularity.csv ├── Employee_Sample_Data.csv ├── brodhead_center.csv ├── data.csv └── student_satisfaction_test-data_from_qualtrics.sav ├── eda.qmd ├── functions.qmd ├── images ├── DALL-E_2023-07-12_learn_R-coding.png ├── DALL-E_2023-07-13_learn_R.png ├── DALL-E_2023-07-13_learn_R_orignal.png ├── Little_reproducibility_project_pyramid.jpg ├── Little_reproducibility_project_pyramid.svg ├── age_ultra_runners.svg ├── arrange_rows.svg ├── console.jpg ├── data_import.jpg ├── data_import_code.jpg ├── filter_by_rows.svg ├── gganmimate_example.gif ├── github_download.jpg ├── install_packages.jpg ├── install_r.jpg ├── join_diagram.png ├── mutate.svg ├── new_quarto_document.jpg ├── package_tidyverse.jpg ├── packages_load.jpg ├── packages_run.jpg ├── prefers_global_options.jpg ├── prefers_global_options_general.jpg ├── prefers_global_options_pipe.jpg ├── projects.jpg ├── quarto.jpg ├── quarto_project.jpg ├── rfun_logo.png ├── select.svg ├── tidy_data.png └── visualization-themes.png ├── import.qmd ├── index.qmd ├── interactive.qmd ├── join.qmd ├── longer_wider.qmd ├── map_import_clean_regex.qmd ├── netlify.toml ├── outline.qmd ├── packages.qmd ├── proj.qmd ├── publish.yml ├── purrr.qmd ├── quarto.qmd ├── references.bib ├── regression.qmd ├── schedule.qmd ├── styles.css ├── tidy_tuesday_itra.qmd ├── tidymodels.qmd ├── viz.qmd ├── widgets.qmd └── wrangle.qmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^LICENSE\.md$ 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.Rmd linguist-language=R 2 | *.R linguist-language=R 3 | *.qmd linguist-language=R 4 | *.html linguist-documentation 5 | *.css linguist-documentation 6 | *.js linguist-documentation 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .Rdata 4 | .httr-oauth 5 | .DS_Store 6 | .quarto 7 | 8 | /.quarto/ 9 | /_site/ 10 | -------------------------------------------------------------------------------- /Intro2R.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction to R workshop 2 | 3 | 4 | 5 | 6 | 7 | For more information or resource on learning R, please visit the [Rfun learning series](https://Rfun.library.duke.edu). 8 | 9 | This website is composed in the [RStudio IDE](https://posit.co/download/rstudio-desktop/), as [R code](https://en.wikipedia.org/wiki/R_(programming_language)) authored as a [Quarto](https://quarto.org/) notebooks. With Quarto it is easy to render multiple report formats, such as a PDF document or this website. In this case the report format is a [web site hosted](https://intro2R.library.duke.edu/) at netlify. The code for this workshop and this webpage are all part of a single RStudio project that can be [found in a GitHub repository](https://github.com/data-and-visualization/Intro2R/). 10 | 11 | The code-along exercises for this workshop are in the GitHub repository but they are not part of the web site. You can work through the exercises by first downloading the GitHub repository. Then, find the exercises within the `_exercises` directory. 12 | 13 | ```{=html} 14 | 21 | ``` 22 | -------------------------------------------------------------------------------- /_exercises/00_import_data.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exercise 0" 3 | 4 | date-modified: 'today' 5 | date-format: long 6 | 7 | format: 8 | html: 9 | footer: "CC BY 4.0 John R Little" 10 | 11 | license: CC BY 12 | --- 13 | 14 | Goals: 15 | 16 | - Create a R Notebook 17 | - Import a dataset using `reader::read_csv()` 18 | 19 | > ANSWER can be found in exercise_00_answers.Rmd file 20 | 21 | ## Exercise: Data Structures & Vector Types 22 | 23 | 1. Load the tidyverse libary package 24 | 25 | ```{r} 26 | #| message: false 27 | #| warning: false 28 | library(tidyverse) 29 | ``` 30 | 31 | 2. Fill in the blanks. Using what you've seen in class, if `data/brodhead_center.csv` is a CSV (comma separated values) file, how would you load the file into a new object called `brodhead`? 32 | - Hint 1. the `data` directory is parallel (over from) the `exercises` directory. You'll need to use relative file paths to refer to this location: \/data/file\ 33 | Often people find using the {here} package is easiest. e.g. `read_csv(here::here("data", "file")` 34 | - Hint 2. the `data` directory is parallel (over from) the `exercises` directory. `..` is a way to move up a directory. `../data` is a way to indicate the location of the data directory. Then add the filename after the slash. Or use the Import Data wizard from the *Environment* tab -- but be sure to copy the code from the wizard into the code-chunk in the notebook. 35 | 36 | ```{r} 37 | _____ <- read_csv(________) 38 | ``` 39 | 40 | 3. Display your new `brodhead` data frame? 41 | 42 | ```{r} 43 | 44 | ``` 45 | 46 | 4. `starwars` is an on-board dataset that comes with the tidyverse. Insert a new code chunk and display that data. 47 | 48 | 5. Copy and paste the following code into a new code chunk in your new file. 49 | 50 | ```{r} 51 | starwars %>% 52 | ggplot(aes(fct_infreq(hair_color))) + 53 | geom_bar() + 54 | ggtitle("Hair color frequency for Star Wars Characters") 55 | ``` 56 | 57 | ### BONUS 1 58 | 59 | 6. Take a look at the structure of the `brodhead` object. 60 | 61 | - How many observations (rows) are there? 62 | - How many variables (columns) are there? 63 | - How many of the variables are numeric data? 64 | 65 | HINT: You can use the `glimpse()` function 66 | 67 | > ANSWER can be found in exercise_00_answers.Rmd file 68 | 69 | ### BONUS 2 70 | 71 | 1. Import SPSS data containing labeled vectors: `data/student_satisfaction_test_data_from_qualtrics.sav` 72 | 73 | 2. Convert the labeled vector field `Q2` to its labeled values with `haven::as_factor()` and `mutate()` 74 | 75 | Hints: 76 | 77 | - The {`here`} package is helpful for navigating to the data directory 78 | 79 | - Notice the data-types of the variables. Using `glimpse()` or simply displaying the data frame, notice the data type: `` used for some columns. 80 | 81 | ```{r} 82 | library(haven) 83 | library(here) 84 | 85 | my_labeled_vectors_df <- 86 | read_sav(here("data", "student_satisfaction_test-data_from_qualtrics.sav")) 87 | ``` 88 | 89 | ```{r} 90 | my_labeled_vectors_df 91 | 92 | my_labeled_vectors_df |> 93 | select(Q2) |> 94 | mutate(Q2_labels = _________(Q2)) 95 | ``` 96 | -------------------------------------------------------------------------------- /_exercises/01_dplyr.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exercise 01 - dplyr -- data wrangling" 3 | 4 | date-modified: 'today' 5 | date-format: long 6 | 7 | format: 8 | html: 9 | footer: "CC BY 4.0 John R Little" 10 | 11 | license: CC BY 12 | --- 13 | 14 | ## Goals: 15 | 16 | Use dplyr functions to wrangle data 17 | 18 | In this exercise you'll practice the `dplyr` verbs (i.e. *functions*) mentioned in the demonstration. 19 | 20 | - `arrange()` 21 | - `filter()` 22 | - `mutate()` 23 | - `select()` 24 | - `count()` 25 | 26 | ## Directions 27 | 28 | ### Setup 29 | 30 | We've prebuilt a data set that has information about menus in Duke's Brodhead Center (dining hall) from three restaurants. Create a new R Notebook, load the *tidyverse* package, and **load the dining hall dataset**, *as a tibble*. The broadhead dataset is a CSV file in the `data` directory. 31 | 32 | a. Add a code chunk and Load the `tidyverse` library package 33 | 34 | ```{r} 35 | #| warning: false 36 | #| message: false 37 | library(tidyverse) 38 | ``` 39 | 40 | b. Insert a code chunk and import (`read_csv()`) the brodhead practice data from the `data` directory. Assign the imported data to an object name, e.g. "brodhead" 41 | 42 | ```{r} 43 | #| warning: false 44 | #| message: false 45 | brodhead <- read_csv("../data/brodhead_center.csv") 46 | ``` 47 | 48 | Now you are ready to make new code chunks and follow the steps in Exercise 1 (below). 49 | 50 | > Answers can be found in the exercise_01_answers.Rmd file 51 | 52 | ### Exercise: Data Wrangling 53 | 54 | All of the following questions are based on the sample of restaurants represented in the dataset which is accurate as of September 2, 2016. 55 | 56 | 1. Which restaurant has the lowest cost item and what is the item? 57 | 58 | ```{r} 59 | brodhead %>% 60 | _______(cost) %>% 61 | select(name, type, itemName, cost) 62 | ``` 63 | 64 | 2. Which restaurant has the most expensive item(s)? What are those item(s)? 65 | 66 | ```{r} 67 | brodhead %>% 68 | ____(____(cost)) %>% 69 | select(name, type, itemName, cost) 70 | ``` 71 | 72 | 3. At the Brodhead Center, how many of the entrees (found in the `menuType` variable) cost eight dollars? 73 | 74 | ```{r} 75 | brodhead %>% 76 | ______(cost == _, menuType == "______") %>% 77 | select(name, menuType, itemName, cost) 78 | ``` 79 | 80 | 4. The head of Duke dining is considering reducing prices at the Brodhead Center. Using what we've learned in class, write code that will calculate a new variable (`halfPrice`) that contains items at half price. 81 | 82 | ```{r} 83 | brodhead %>% 84 | ______(halfPrice = (____ / 2)) %>% 85 | select(name, itemName, cost, halfPrice) 86 | ``` 87 | 88 | 5. How many entrees are in the dataset (`menuType` variable)? How many desserts 89 | 90 | ```{r} 91 | brodhead %>% 92 | _____(menuType) 93 | # You can use `filter()` to limit by menuType 94 | ``` 95 | 96 | ## Answers 97 | 98 | > Answers can be found in the `_exercise_01/answers/01_dplyr_answers.qmd` file 99 | 100 | ## Optional 101 | 102 | [Interactive quiz](https://posit.cloud/learn/primers/2.2) 103 | -------------------------------------------------------------------------------- /_exercises/02_viz.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Visualize Data in R with ggplot2" 3 | subtitle: "Exercises" 4 | abstract: "These exercises are adapted in whole or in part based on the Master the Tidyverse work by Garrett Grolemund at RStudio. \nCC BY Garrett Grolemund, RStudio ; BY-NC John Little" 5 | 6 | date-modified: 'today' 7 | date-format: long 8 | 9 | format: 10 | html: 11 | footer: "CC BY 4.0 John R Little" 12 | 13 | license: CC BY 14 | --- 15 | 16 | These exercises support your learning after watching the [instructional video](https://warpwire.duke.edu/w/80YEAA/) 17 | 18 | ```{r setup} 19 | #| echo: true 20 | #| warning: false 21 | #| message: false 22 | library(tidyverse) 23 | ``` 24 | 25 | The dataset, `mpg`, is an onboard dataset, part of the `ggplot2` package. You can learn more about it by searching the help tab for "mpg", or type `?mpg` in the console. 26 | 27 | ```{r} 28 | mpg 29 | ``` 30 | 31 | ## Your Turn 1 32 | 33 | IN THE code-chunk, **below**, manually type the following code: 34 | 35 | ggplot(data = mpg) + geom_point(mapping = aes(x = displ, y = hwy)) 36 | 37 | Pay strict attention to spelling, capitalization, and parentheses! Try not to copy and paste, just this once. 38 | 39 | ```{r} 40 | #| eval: false 41 | ``` 42 | 43 | ## Your Turn 2 44 | 45 | Add `color`, `size`, `alpha`, and `shape` aesthetics to your graph. Experiment. 46 | 47 | ```{r} 48 | mpg %>% 49 | ggplot() + 50 | geom_point(mapping = aes(x = displ, y = hwy)) 51 | ``` 52 | 53 | ## Your Turn 3 54 | 55 | Replace this scatter plot with one that draws box plots. Use the cheat sheet. Try your best guess. 56 | 57 | ```{r} 58 | mpg %>% 59 | ggplot() + 60 | geom_point(aes(class, hwy)) 61 | ``` 62 | 63 | ## Your Turn 4 64 | 65 | Make a histogram of the `hwy` variable from `mpg`. 66 | 67 | ```{r} 68 | 69 | ``` 70 | 71 | ## Your Turn 5 72 | 73 | Make a density plot of `hwy` colored by `class`. 74 | 75 | ```{r} 76 | 77 | ``` 78 | 79 | ## Your Turn 6 80 | 81 | Make a bar chart `hwy` colored by `class`. 82 | 83 | ```{r} 84 | 85 | ``` 86 | 87 | ## Your Turn 7 88 | 89 | Predict what this code will do. Then run it. 90 | 91 | ```{r} 92 | mpg %>% 93 | ggplot() + 94 | geom_point(aes(displ, hwy)) + 95 | geom_smooth(aes(displ, hwy)) 96 | ``` 97 | 98 | ## Your Turn 8 99 | 100 | Save the last plot 101 | 102 | ```{r} 103 | ggsave(_____) 104 | # or right-click the image 105 | ``` 106 | -------------------------------------------------------------------------------- /_exercises/02_viz_interactivity.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Visualization interactivity" 3 | --- 4 | 5 | ## Load library package 6 | 7 | ```{r} 8 | #| warning: false 9 | #| message: false 10 | library(tidyverse) 11 | ``` 12 | 13 | Make a barplot of the `gender` of starwars charactesrs 14 | 15 | ```{r} 16 | starwars |> 17 | ggplot(aes(gender)) + 18 | geom_bar() 19 | 20 | ``` 21 | 22 | Make a stacked bar plot, as above, using the `fill` argument. Stack the bars with the values of the `sex` variable. Assign the plot to an object name of `star_gender`. 23 | 24 | ```{r} 25 | _________ <- starwars |> 26 | ggplot(aes(gender)) + 27 | geom_bar(aes(____ = sex)) 28 | star_gender 29 | ``` 30 | 31 | Using the {`plotly`} package 32 | 33 | ```{r} 34 | library(plotly) 35 | ``` 36 | 37 | Make the `star_gender` object interactive 38 | 39 | ```{r} 40 | ggplotly(________) 41 | ``` 42 | -------------------------------------------------------------------------------- /_exercises/03_pivot.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "03 pivot data" 3 | author: "John Little" 4 | 5 | date-modified: 'today' 6 | date-format: long 7 | 8 | format: 9 | html: 10 | footer: "CC BY 4.0 John R Little" 11 | 12 | license: CC BY 13 | --- 14 | 15 | ```{r} 16 | library(tidyverse) 17 | ``` 18 | 19 | ## data 20 | 21 | These exercises use the following [`ggplot2` training datasets](https://ggplot2.tidyverse.org/reference/index.html#section-data) 22 | 23 | - ggplot2::economics 24 | 25 | ## Pivot 26 | 27 | Below are two data frames. One is wide data, the other is long. 28 | 29 | ```{r} 30 | economics 31 | economics_long %>% arrange(date) 32 | ``` 33 | 34 | ## Goal 35 | 36 | Using one of the dplyr pivot functions, pivot the economics data to long format 37 | 38 | ```{r} 39 | economics %>% 40 | pivot_------(cols = pce:unemploy, 41 | names_to = "variable", 42 | values_to = "value") 43 | ``` 44 | 45 | Now that the data are long. Can you use the `facet_wrap()` function to make multiple line plots, one line plot for each `variable` category? 46 | 47 | ```{r} 48 | economics |> 49 | pivot_longer(-date, names_to = "variable", values_to = "value") |> 50 | ggplot(aes(date, value)) + 51 | geom____() + 52 | facet_wrap(vars(_______)) 53 | ``` 54 | -------------------------------------------------------------------------------- /_exercises/04_join.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "join" 3 | 4 | date-modified: 'today' 5 | date-format: long 6 | 7 | format: 8 | html: 9 | footer: "CC BY 4.0 John R Little" 10 | 11 | license: CC BY 12 | --- 13 | 14 | ```{r} 15 | library(tidyverse) 16 | ``` 17 | 18 | ## Join 19 | 20 | There are a series of [join commands](https://dplyr.tidyverse.org/reference/index.html#section-two-table-verbs) 21 | 22 | - left_join, inner_join, right_join, full_join, 23 | - semi_join, anti_join 24 | 25 | ![dplyr joins visualized](https://pbs.twimg.com/media/B6eUTTACUAAahLf.png) 26 | 27 | ## data 28 | 29 | These exercises use the following [`dplyr` datasets](https://ggplot2.tidyverse.org/reference/index.html#section-data) 30 | 31 | - dplyr::band_instruments 32 | - dplyr::band_members 33 | 34 | ```{r} 35 | band_members 36 | band_instruments 37 | ``` 38 | 39 | ## Goal 40 | 41 | Make one big data frame that joins `band_members` with `band_instruments`. Using the template below you need to identify what type of join to use and identify the join key. 42 | 43 | ```{r} 44 | #| eval: false 45 | band_members |> 46 | ----_join(band_instruments, by = "----") 47 | ``` 48 | -------------------------------------------------------------------------------- /_exercises/05_functions_exercise.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exercise 03" 3 | subtitle: "functions" 4 | --- 5 | 6 | Compose a function to take the square root, `sqrt()`, of a number which is multiplied by 10 7 | 8 | ```{r} 9 | library(tidyverse) 10 | ``` 11 | 12 | ```{r} 13 | sqrt_by_10 <- function(my_x) { 14 | _____(my_x * __) 15 | } 16 | ``` 17 | 18 | Execute the function 19 | 20 | ```{r} 21 | sqrt_by_10(______) 22 | 23 | sqrt(3 * 10) 24 | ``` 25 | 26 | Compose a function that multiplies two numbers 27 | 28 | ```{r} 29 | multiply_two_numbers <- function(_ , _) { 30 | (_ * _) 31 | } 32 | ``` 33 | 34 | Execute the function 35 | 36 | ```{r} 37 | starwars |> 38 | mutate(new_number = multiply_two_numbers(___, ____), .after = mass) 39 | ``` 40 | -------------------------------------------------------------------------------- /_exercises/06_nest_exercise.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exercise 04" 3 | subtitle: "nest a list column of data frames and iterate a function with `purrr::map()`" 4 | --- 5 | 6 | ```{r} 7 | library(tidyverse) 8 | library(lubridate) 9 | # library(gapminder) 10 | ``` 11 | 12 | Using one of the on-board data sets, nest data by a categorical element. Note: the data type you use for nesting does not have to be a factor data type. Feel free to use your own data set if you prefer, but the following are easily accessible, especially if you've previously loaded either the tidyverse or gapminder packages: `starwars`; `fish_encounters`; `mpg`; `mtcars`; `economics_long`; `lubridate::lakers`; `gapminder::gapminder` 13 | 14 | ```{r} 15 | gapminder::gapminder |> 16 | nest(-________) 17 | 18 | gapminder::gapminder |> 19 | group_by(_______) |> 20 | nest() 21 | ``` 22 | 23 | ## A function 24 | 25 | Here's a function that you can use. Execute the code chunk below an move to the next section. 26 | 27 | ```{r} 28 | my_first_plot_function <- function(my_df) { 29 | my_df |> 30 | ggplot(aes(year, pop)) + 31 | geom_line(aes(color = country)) 32 | } 33 | ``` 34 | 35 | ## Practice iterating 36 | 37 | Use the above function, `my_first_plot_function`, with `purrr::map()` 38 | 39 | You many need to install the {`gapminder`} package. Make a nested data frame by `continent`. Use `purr::map()` to apply the custom function, `my_first_plot_function`, to the gapminder data set as a new variable: `my_plot`. Then, use the `pull()` function to view the new plots 40 | 41 | ```{r} 42 | gapminder::gapminder |> 43 | nest(-continent) |> 44 | mutate(my_plot = map(data, ____________)) #|> pull(my_plot) 45 | ``` 46 | 47 | You can create the same outcome as above with an anonymous function.\ 48 | a. What is `.x`?\ 49 | b. what is `~`? 50 | 51 | ```{r} 52 | gapminder::gapminder |> 53 | nest(-continent) |> 54 | mutate(my_plot = map(data, ~ .x |> ggplot(aes(year, pop)) + geom_line(aes(color = country)))) |> 55 | pull(my_plot) 56 | 57 | ``` 58 | 59 | Below is an artifact of troubleshooting. As time allows, I'll demonstrate this process in the workshop. 60 | 61 | ```{r} 62 | make_my_plot <- function(my_df, my_name) { 63 | my_df |> 64 | ggplot(aes(year, total)) + 65 | geom_point() + 66 | geom_line(aes(group = {{my_name}})) + 67 | labs(title = {{my_name}}) 68 | } 69 | 70 | babynames::babynames |> 71 | filter(name == "John" | name == "Elizabeth") |> 72 | group_by(year, name) |> 73 | summarise(total = sum(n), .groups = "drop") |> 74 | nest(-name) |> # head(1) |> unnest() # |> 75 | # ggplot(aes(year, total)) + 76 | # geom_point() 77 | # mutate(my_plot = map(data, make_my_plot)) |> 78 | mutate(my_plot = map2(data, name, make_my_plot)) |> 79 | pull(my_plot) 80 | 81 | ``` 82 | -------------------------------------------------------------------------------- /_exercises/answers/00_import_answers.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Answers - Excercise 00" 3 | 4 | date-modified: 'today' 5 | date-format: long 6 | 7 | format: 8 | html: 9 | footer: "CC BY 4.0 John R Little" 10 | 11 | license: CC BY 12 | --- 13 | 14 | ## exercise 00: 15 | 16 | 1. Load the tidyverse libary package 17 | 18 | ```{r} 19 | #| message: false 20 | #| warning: false 21 | library(tidyverse) 22 | ``` 23 | 24 | 2. Fill in the blanks. Using what you've seen in class, if `data/brodhead_center.csv` is a CSV (comma separated values) file, how would you load the file into a new object called `brodhead`? 25 | 26 | ```{r} 27 | #| message: false 28 | #| warning: false 29 | brodhead <- read_csv("../../data/brodhead_center.csv") 30 | 31 | # or 32 | # brodhead <- read_csv(here::here("data", "brodhead_center.csv")) 33 | ``` 34 | 35 | 3. Display your new `brodhead` data frame? 36 | 37 | ```{r} 38 | brodhead 39 | ``` 40 | 41 | 4. `starwars` is an on-board dataset that comes with the tidyverse. Insert a new code chunk and display that data. 42 | 43 | ```{r} 44 | starwars 45 | ``` 46 | 47 | 5. Copy and paste the following code into a new code chunk in your new file. 48 | 49 | ```{r} 50 | starwars %>% 51 | ggplot(aes(fct_infreq(hair_color))) + 52 | geom_bar() + 53 | ggtitle("Hair Color Frequency of Star Wars Characters") 54 | ``` 55 | 56 | 6. Take a look at the structure of the `brodhead` object. 57 | - How many observations (rows) are there? 58 | - How many variables (columns) are there? 59 | - How many of the variables are numeric data? 60 | 61 | ```{r} 62 | glimpse(brodhead) 63 | ``` 64 | 65 | ## Bonus 2 66 | 67 | Importing labeled vectors from an spss file format. Import via the `haven::read_sav()` function 68 | 69 | ```{r} 70 | library(haven) 71 | library(here) 72 | 73 | my_labeled_vectors_df <- 74 | read_sav(here("data", "student_satisfaction_test-data_from_qualtrics.sav")) 75 | 76 | my_labeled_vectors_df 77 | 78 | my_labeled_vectors_df |> 79 | select(Q2) |> 80 | mutate(Q2_labels = as_factor(Q2)) 81 | 82 | my_labeled_vectors_df |> 83 | select(ResponseId, starts_with("Q")) |> 84 | mutate(across(is.labelled, function(x) as_factor(x), .names = "{.col}_label")) |> 85 | select(ResponseId, sort(tidyselect::peek_vars())) 86 | 87 | ``` 88 | -------------------------------------------------------------------------------- /_exercises/answers/01_dplyr_answers.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Answers 01 - dplyr -- data wrangling" 3 | 4 | date-modified: 'today' 5 | date-format: long 6 | 7 | format: 8 | html: 9 | footer: "CC BY 4.0 John R Little" 10 | 11 | license: CC BY 12 | --- 13 | 14 | ### Setup 15 | 16 | a. Load the `tidyverse` library package 17 | 18 | ```{r} 19 | #| message: false 20 | #| warning: false 21 | library(tidyverse) 22 | ``` 23 | 24 | b. Import data 25 | 26 | ```{r} 27 | #| message: false 28 | #| warning: false 29 | library(here) 30 | brodhead <- read_csv(here("data", "brodhead_center.csv")) 31 | ``` 32 | 33 | ### exercise_01 -- Data Wrangling 34 | 35 | 1. Which restaurant has the lowest cost item and what is the item? 36 | 37 | ```{r} 38 | brodhead %>% 39 | arrange(cost) %>% 40 | select(name, type, itemName, cost) 41 | ``` 42 | 43 | #### Alternative Answer 44 | 45 | ```{r} 46 | lowest_cost_item <- brodhead %>% 47 | arrange(cost) %>% 48 | select(name) %>% 49 | slice_head() %>% 50 | pull() 51 | lowest_cost_item 52 | ``` 53 | 54 | The lowest cost item can be found at `r lowest_cost_item`. 55 | 56 | 2. Which restaurant has the most expensive item(s)? What are those item(s)? 57 | 58 | ```{r} 59 | brodhead %>% 60 | arrange(desc(cost)) %>% 61 | select(name, type, itemName, cost) 62 | ``` 63 | 64 | #### Alternative Answers 65 | 66 | ```{r} 67 | answer2 <- brodhead %>% 68 | select(name, type, itemName, cost) %>% 69 | filter(type == "restaurant", 70 | cost == max(cost)) 71 | answer2 72 | ``` 73 | 74 | ```{r} 75 | expensive_items <- brodhead %>% 76 | select(name, type, itemName, cost) %>% 77 | filter(type == "restaurant", 78 | cost == max(cost)) %>% 79 | select(name, itemName) 80 | 81 | expensive_items 82 | ``` 83 | 84 | **Example of inline coding** (Render report to see result.) 85 | 86 | The `r unique(expensive_items$name)` restaurant offers the following items at the highest cost: `r expensive_items$itemName`. 87 | 88 | 3. At the Brodhead Center, how many of the entrees (found in the `menuType` variable) cost eight dollars? 89 | 90 | ```{r} 91 | brodhead %>% 92 | filter(cost == 8, menuType == "entree") %>% 93 | select(name, menuType, itemName, cost) 94 | ``` 95 | 96 | The **answer** is 8. You know this because the Tibble (data frame) has 8 rows. 97 | 98 | #### Alternative Answer 99 | 100 | ```{r} 101 | brodhead %>% 102 | filter(cost == 8, menuType == "entree") %>% 103 | select(name, menuType, itemName, cost) %>% 104 | count(menuType) 105 | ``` 106 | 107 | #### Alternative Answer 108 | 109 | ```{r} 110 | eight_dollar_items <- brodhead %>% 111 | filter(cost == 8, menuType == "entree") %>% 112 | select(name, menuType, itemName, cost) 113 | 114 | length(eight_dollar_items$itemName) 115 | ``` 116 | 117 | 4. The head of Duke dining is considering reducing prices at the Brodhead Center. Using what we've learned in class, write code that will calculate a new variable (`halfPrice`) that contains items at half price. 118 | 119 | ```{r} 120 | brodhead %>% 121 | mutate(halfPrice = (cost / 2)) %>% 122 | select(name, itemName, cost, halfPrice) %>% 123 | mutate(halfPrice = scales::dollar(halfPrice)) 124 | ``` 125 | 126 | 5. How many entrees are in the dataset (`menuType` variable)? How many desserts 127 | 128 | ```{r} 129 | brodhead %>% 130 | count(menuType) 131 | # You can use `filter()` to limit by menuType 132 | ``` 133 | 134 | #### Alternative Answer 135 | 136 | ```{r} 137 | brodhead %>% 138 | count(menuType) %>% 139 | filter(menuType == "entree") %>% 140 | pull(n) 141 | ``` 142 | 143 | ```{r} 144 | #| echo: false 145 | my_answer <- brodhead %>% 146 | count(menuType) %>% 147 | filter(menuType == "entree") %>% 148 | pull(n) 149 | ``` 150 | 151 | There are `r my_answer` entrees. 152 | -------------------------------------------------------------------------------- /_exercises/answers/02_viz_ggplot2_answers.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Visualize Data in R with ggplot2" 3 | subtitle: "Exercises" 4 | abstract: "These exercises are adapated in whole or in part based on the Master the Tidyverse work by Garrett Grolemund at RStudio. \nCC BY Garrett Grolemund, RStudio ; BY-NC John Little" 5 | 6 | date-modified: 'today' 7 | date-format: long 8 | 9 | format: 10 | html: 11 | footer: "CC BY 4.0 John R Little" 12 | 13 | license: CC BY 14 | --- 15 | 16 | ```{r setup} 17 | library(tidyverse) 18 | ``` 19 | 20 | ```{r} 21 | mpg 22 | ``` 23 | 24 | ## Your Turn 1 25 | 26 | Run the code on the slide to make a graph. Pay strict attention to spelling, capitalization, and parentheses! 27 | 28 | ```{r} 29 | ggplot(data = mpg) + 30 | geom_point(mapping = aes(x = displ, y = hwy)) 31 | ``` 32 | 33 | ## Your Turn 2 34 | 35 | Add `color`, `size`, `alpha`, and `shape` aesthetics to your graph. Experiment. 36 | 37 | ```{r} 38 | #| fig-height: 7 39 | mpg %>% 40 | ggplot() + 41 | geom_point(mapping = aes(x = displ, y = hwy, 42 | color = class, 43 | size = cyl, 44 | shape = drv, 45 | alpha = hwy)) 46 | ``` 47 | 48 | ## Your Turn 3 49 | 50 | Replace this scatterplot with one that draws boxplots. Use the cheatsheet. Try your best guess. 51 | 52 | ```{r} 53 | mpg %>% 54 | ggplot() + 55 | geom_point(aes(class, hwy)) 56 | 57 | mpg %>% 58 | ggplot() + 59 | geom_boxplot(aes(class, hwy)) 60 | ``` 61 | 62 | ## Your Turn 4 63 | 64 | Make a histogram of the `hwy` variable from `mpg`. 65 | 66 | ```{r} 67 | mpg %>% 68 | ggplot() + 69 | geom_histogram(aes(hwy)) 70 | ``` 71 | 72 | ```{r} 73 | mpg %>% 74 | ggplot() + 75 | geom_histogram(aes(hwy), binwidth = 2) 76 | ``` 77 | 78 | ## Your Turn 5 79 | 80 | Make a density plot of `hwy` colored by `class`. 81 | 82 | ```{r} 83 | mpg %>% 84 | ggplot() + 85 | geom_density(mapping = aes(x = hwy, color = class)) 86 | ``` 87 | 88 | ## Your Turn 6 89 | 90 | Make a bar chart `hwy` colored by `class`. 91 | 92 | ```{r} 93 | mpg %>% 94 | ggplot() + 95 | geom_bar(mapping = aes(x = class, color = class)) 96 | ``` 97 | 98 | ```{r} 99 | mpg %>% 100 | ggplot() + 101 | geom_bar(mapping = aes(x = class, fill = class)) 102 | ``` 103 | 104 | ## Your Turn 7 105 | 106 | Predict what this code will do. Then run it. 107 | 108 | ```{r} 109 | mpg %>% 110 | ggplot() + 111 | geom_point(aes(displ, hwy)) + 112 | geom_smooth(aes(displ, hwy)) 113 | ``` 114 | 115 | ## Your Turn 8 116 | 117 | Save the last plot. 118 | 119 | ``` r 120 | ggsave("mylastplot.png") 121 | # or right-click the image 122 | ``` 123 | -------------------------------------------------------------------------------- /_exercises/answers/02_viz_interactivity_answers.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Visualization interactivity" 3 | --- 4 | 5 | ## Load library package 6 | 7 | ```{r} 8 | #| warning: false 9 | #| message: false 10 | library(tidyverse) 11 | ``` 12 | 13 | Make a barplot of the `gender` of starwars charactesrs 14 | 15 | ```{r} 16 | starwars |> 17 | ggplot(aes(gender)) + 18 | geom_bar() 19 | 20 | ``` 21 | 22 | Make a stacked barplot using the `fill` argument. Stack the bars with the values of the `sex` variable. Assign the plot to an object name: `star_gender`. 23 | 24 | ```{r} 25 | star_gender <- starwars |> 26 | ggplot(aes(gender)) + 27 | geom_bar(aes(fill = sex)) 28 | star_gender 29 | ``` 30 | 31 | ```{r} 32 | library(plotly) 33 | ``` 34 | 35 | ```{r} 36 | ggplotly(star_gender) 37 | ``` 38 | -------------------------------------------------------------------------------- /_exercises/answers/03_pivot_answers.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "03 pivot data" 3 | author: "John Little" 4 | 5 | date-modified: 'today' 6 | date-format: long 7 | 8 | format: 9 | html: 10 | footer: "CC BY 4.0 John R Little" 11 | 12 | license: CC BY 13 | --- 14 | 15 | ```{r} 16 | library(tidyverse) 17 | ``` 18 | 19 | ## data 20 | 21 | These exercises use the following [`ggplot2` training datasets](https://ggplot2.tidyverse.org/reference/index.html#section-data) 22 | 23 | - ggplot2::economics 24 | 25 | ## Pivot 26 | 27 | Below are two data frames. One is wide data, the other is long. 28 | 29 | ```{r} 30 | economics 31 | economics_long %>% arrange(date) 32 | ``` 33 | 34 | ## Goal 35 | 36 | Using one of the dplyr pivot functions, pivot the economics data to long format 37 | 38 | ```{r} 39 | economics %>% 40 | pivot_longer(cols = pce:unemploy, 41 | names_to = "variable", 42 | values_to = "value") 43 | ``` 44 | 45 | or 46 | 47 | ```{r} 48 | economics |> 49 | pivot_longer(-date, names_to = "variable", values_to = "value") 50 | ``` 51 | 52 | Now that the data are long. Can you use the `facet_wrap()` function to make multiple line plots, one line plot for each `variable` category? 53 | 54 | ```{r} 55 | economics |> 56 | pivot_longer(-date, names_to = "variable", values_to = "value") |> 57 | ggplot(aes(date, value)) + 58 | geom_line() + 59 | facet_wrap(vars(variable)) 60 | ``` 61 | -------------------------------------------------------------------------------- /_exercises/answers/04_join_answers.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "join" 3 | 4 | date-modified: 'today' 5 | date-format: long 6 | 7 | format: 8 | html: 9 | footer: "CC BY 4.0 John R Little" 10 | 11 | license: CC BY 12 | --- 13 | 14 | ```{r} 15 | library(tidyverse) 16 | ``` 17 | 18 | ## Join 19 | 20 | There are a series of [join commands](https://dplyr.tidyverse.org/reference/index.html#section-two-table-verbs) 21 | 22 | - left_join, inner_join, right_join, full_join, 23 | - semi_join, anti_join 24 | 25 | ![dplyr joins visualized](https://pbs.twimg.com/media/B6eUTTACUAAahLf.png) 26 | 27 | ## data 28 | 29 | These exercises use the following [`dplyr` datasets](https://ggplot2.tidyverse.org/reference/index.html#section-data) 30 | 31 | - dplyr::band_instruments 32 | - dplyr::band_members 33 | 34 | ```{r} 35 | band_members 36 | band_instruments 37 | ``` 38 | 39 | ## Goal 40 | 41 | Make one big data frame that joins `band_members` with `band_instruments`. Using the template below you need to identify what type of join to use and identify the join key. 42 | 43 | ```{r} 44 | band_members |> 45 | left_join(band_instruments, by = "name") 46 | ``` 47 | -------------------------------------------------------------------------------- /_exercises/answers/05_functions_answers.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exercise 03" 3 | subtitle: "functions" 4 | --- 5 | 6 | Compose a function to take the square root, `sqrt()`, of a number which is multiplied by 10 7 | 8 | ```{r} 9 | library(tidyverse) 10 | ``` 11 | 12 | ```{r} 13 | sqrt_by_10 <- function(my_x) { 14 | sqrt(my_x * 10) 15 | } 16 | ``` 17 | 18 | Execute the function 19 | 20 | ```{r} 21 | sqrt_by_10(3) 22 | 23 | sqrt(3 * 10) 24 | ``` 25 | 26 | Compose a function that multiplies two numbers 27 | 28 | ```{r} 29 | multiply_two_numbers <- function(x, y) { 30 | (x * y) 31 | } 32 | ``` 33 | 34 | Execute the function 35 | 36 | ```{r} 37 | starwars |> 38 | mutate(new_number = multiply_two_numbers(mass, height), .after = mass) 39 | ``` 40 | -------------------------------------------------------------------------------- /_exercises/answers/06_nest_answers.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Exercise 04" 3 | subtitle: "nest a list column of data frames and iterate a function with `purrr::map()`" 4 | --- 5 | 6 | ```{r} 7 | library(tidyverse) 8 | library(lubridate) 9 | library(gapminder) 10 | ``` 11 | 12 | Using one of the on-board data sets, nest data by a categorical element. Note: the data type you use for nesting does not have to be a factor data type. Feel free to use your own data set if you prefer, but the following are easily accessible, especially if you've previously loaded either the tidyverse or gapminder packages: `starwars`; `fish_encounters`; `mpg`; `mtcars`; `economics_long`; `lubridate::lakers`; `gapminder::gapminder` 13 | 14 | ```{r} 15 | gapminder::gapminder |> 16 | nest(-continent) 17 | 18 | gapminder::gapminder |> 19 | group_by(year) |> 20 | nest() 21 | ``` 22 | 23 | ## A function 24 | 25 | Here's a function that you can use. Execute the code chunk below an move to the next section. 26 | 27 | ```{r} 28 | my_first_plot_function <- function(my_df) { 29 | my_df |> 30 | ggplot(aes(year, pop)) + 31 | geom_line(aes(color = country)) 32 | } 33 | ``` 34 | 35 | ## Practice iterating 36 | 37 | Use the above function, `my_first_plot_function`, with `purrr::map()` 38 | 39 | You many need to install the {`gapminder`} package. Make a nested data frame by `continent`. Use `purr::map()` to apply the custom function, `my_first_plot_function`, to the gapminder data-set as a new variable: `my_plot`. Then, use the `pull()` function to view the new plots 40 | 41 | ```{r} 42 | gapminder::gapminder |> 43 | nest(-continent) |> 44 | mutate(my_plot = map(data, my_first_plot_function)) #|> pull(my_plot) 45 | ``` 46 | 47 | You can create the same outcome as above with an anonymous function. 48 | 49 | ```{r} 50 | gapminder::gapminder |> 51 | nest(-continent) |> 52 | mutate(my_plot = map(data, function(x) x |> ggplot(aes(year, pop)) + geom_line(aes(color = country)))) |> 53 | pull(my_plot) 54 | 55 | ``` 56 | 57 | Below is an artifact of troubleshooting. As time allows, I'll demonstrate this process in the workshop. 58 | 59 | ```{r} 60 | make_my_plot <- function(my_df, my_name) { 61 | my_df |> 62 | ggplot(aes(year, total)) + 63 | geom_point() + 64 | geom_line(aes(group = {{my_name}})) + 65 | labs(title = {{my_name}}) 66 | } 67 | 68 | babynames::babynames |> 69 | filter(name == "John" | name == "Elizabeth") |> 70 | group_by(year, name) |> 71 | summarise(total = sum(n), .groups = "drop") |> 72 | nest(-name) |> # head(1) |> unnest() # |> 73 | # ggplot(aes(year, total)) + 74 | # geom_point() 75 | # mutate(my_plot = map(data, make_my_plot)) |> 76 | mutate(my_plot = map2(data, name, make_my_plot)) |> 77 | pull(my_plot) 78 | 79 | ``` 80 | -------------------------------------------------------------------------------- /_freeze/functions/figure-html/unnamed-chunk-2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/functions/figure-html/unnamed-chunk-2-1.png -------------------------------------------------------------------------------- /_freeze/functions/figure-html/unnamed-chunk-2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/functions/figure-html/unnamed-chunk-2-2.png -------------------------------------------------------------------------------- /_freeze/functions/figure-html/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/functions/figure-html/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /_freeze/import/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/import/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /_freeze/import/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/import/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /_freeze/import/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/import/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /_freeze/longer_wider/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/longer_wider/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /_freeze/longer_wider/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/longer_wider/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /_freeze/longer_wider/figure-html/unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/longer_wider/figure-html/unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /_freeze/longer_wider/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/longer_wider/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /_freeze/longer_wider/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/longer_wider/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /_freeze/longer_wider/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/longer_wider/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /_freeze/purrr/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/purrr/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /_freeze/purrr/figure-html/unnamed-chunk-10-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/purrr/figure-html/unnamed-chunk-10-2.png -------------------------------------------------------------------------------- /_freeze/regression/figure-html/unnamed-chunk-15-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/regression/figure-html/unnamed-chunk-15-1.png -------------------------------------------------------------------------------- /_freeze/regression/figure-html/unnamed-chunk-15-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/regression/figure-html/unnamed-chunk-15-2.png -------------------------------------------------------------------------------- /_freeze/regression/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-and-visualization/Intro2R/91d3f2c1fd013901f9073b79685734260d48b2ad/_freeze/regression/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /_freeze/site_libs/core-js-2.5.3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2017 Denis Pushkarev 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /_freeze/site_libs/core-js-2.5.3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@babel/cli": "^7.7.7", 4 | "@babel/core": "^7.7.7", 5 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4", 6 | "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", 7 | "@babel/plugin-proposal-optional-chaining": "^7.7.5", 8 | "@babel/plugin-transform-arrow-functions": "^7.7.4", 9 | "@babel/plugin-transform-block-scoped-functions": "^7.7.4", 10 | "@babel/plugin-transform-block-scoping": "^7.7.4", 11 | "@babel/plugin-transform-classes": "^7.7.4", 12 | "@babel/plugin-transform-computed-properties": "^7.7.4", 13 | "@babel/plugin-transform-destructuring": "^7.7.4", 14 | "@babel/plugin-transform-exponentiation-operator": "^7.7.4", 15 | "@babel/plugin-transform-literals": "^7.7.4", 16 | "@babel/plugin-transform-member-expression-literals": "^7.7.4", 17 | "@babel/plugin-transform-parameters": "^7.7.7", 18 | "@babel/plugin-transform-property-literals": "^7.7.4", 19 | "@babel/plugin-transform-shorthand-properties": "^7.7.4", 20 | "@babel/plugin-transform-spread": "^7.7.4", 21 | "@babel/plugin-transform-template-literals": "^7.7.4", 22 | "babel-loader": "^8.0.6", 23 | "babel-plugin-transform-es2015-modules-simple-commonjs": "~0.3.0", 24 | "babel-plugin-transform-for-of-as-array": "^1.1.1", 25 | "es-observable": "git+https://github.com/tc39/proposal-observable.git#bf4d87144b6189e793593868e3c022eb51a7d292", 26 | "eslint": "^6.8.0", 27 | "eslint-import-resolver-webpack": "^0.12.0", 28 | "eslint-plugin-import": "^2.19.1", 29 | "eslint-plugin-node": "^10.0.0", 30 | "eslint-plugin-optimize-regex": "^1.1.7", 31 | "eslint-plugin-qunit": "^4.0.0", 32 | "eslint-plugin-sonarjs": "^0.5.0", 33 | "eslint-plugin-unicorn": "^15.0.0", 34 | "grunt": "^1.0.4", 35 | "grunt-cli": "^1.3.2", 36 | "grunt-contrib-clean": "^2.0.0", 37 | "grunt-contrib-copy": "^1.0.0", 38 | "grunt-contrib-uglify": "^4.0.1", 39 | "grunt-karma": "^3.0.2", 40 | "grunt-webpack": "^3.1.3", 41 | "karma": "^4.4.1", 42 | "karma-chrome-launcher": "^3.1.0", 43 | "karma-phantomjs-launcher": "~1.0.4", 44 | "karma-qunit": "^4.0.0", 45 | "lerna": "^3.19.0", 46 | "moon-unit": "^0.2.2", 47 | "phantomjs-prebuilt": "~2.1.16", 48 | "promises-aplus-tests": "^2.1.2", 49 | "puppeteer": "~2.0.0", 50 | "qunit": "~2.9.3", 51 | "webpack": "^4.41.4" 52 | }, 53 | "license": "MIT", 54 | "repository": { 55 | "type": "git", 56 | "url": "https://github.com/zloirock/core-js.git" 57 | }, 58 | "scripts": { 59 | "bootstrap": "lerna bootstrap --no-ci", 60 | "build": "grunt clean copy && npm run bootstrap && npm run build-compat && grunt bundle uglify", 61 | "build-compat": "npm run build-compat-data && npm run build-compat-entries && npm run build-compat-modules-by-versions", 62 | "build-compat-data": "node packages/core-js-compat/src/build-data", 63 | "build-compat-entries": "node packages/core-js-compat/src/build-entries", 64 | "build-compat-modules-by-versions": "node packages/core-js-compat/src/build-modules-by-versions", 65 | "lint": "grunt clean copy && npm run bootstrap && npm run build-compat && eslint ./", 66 | "unit-tests": "grunt clean copy && npm run bootstrap && npm run build-compat && grunt bundle webpack:helpers webpack:tests karma:tests", 67 | "unit-tests-pure": "grunt clean copy && npm run build-compat && grunt webpack:helpers webpack:pure karma:pure", 68 | "bundle-promises-tests": "grunt webpack:promises-aplus-tests", 69 | "promises-tests": "promises-aplus-tests tests/promises-aplus/adapter --timeout 1000", 70 | "observables-tests": "babel node_modules/es-observable/test/ -d tests/bundles/observables-tests/ && node tests/observables/adapter && node tests/observables/adapter-pure", 71 | "commonjs-tests": "node tests/commonjs", 72 | "commonjs-entries-content": "node tests/commonjs-entries-content", 73 | "targets-parser-tests": "node tests/targets-parser", 74 | "test": "grunt clean copy && npm run bootstrap && npm run build-compat && eslint ./ && grunt webpack:helpers webpack:tests bundle uglify karma:tests webpack:helpers webpack:pure karma:pure && npm run promises-tests && npm run observables-tests && npm run commonjs-tests && npm run commonjs-entries-content && npm run targets-parser-tests" 75 | }, 76 | "engines": { 77 | "node": ">=8.9.0" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /_freeze/site_libs/crosstalk-1.2.0/css/crosstalk.min.css: -------------------------------------------------------------------------------- 1 | .container-fluid.crosstalk-bscols{margin-left:-30px;margin-right:-30px;white-space:normal}body>.container-fluid.crosstalk-bscols{margin-left:auto;margin-right:auto}.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:inline-block;padding-right:12px;vertical-align:top}@media only screen and (max-width: 480px){.crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column{display:block;padding-right:inherit}}.crosstalk-input{margin-bottom:15px}.crosstalk-input .control-label{margin-bottom:0;vertical-align:middle}.crosstalk-input input[type="checkbox"]{margin:4px 0 0;margin-top:1px;line-height:normal}.crosstalk-input .checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.crosstalk-input .checkbox>label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.crosstalk-input .checkbox input[type="checkbox"],.crosstalk-input .checkbox-inline input[type="checkbox"]{position:absolute;margin-top:2px;margin-left:-20px}.crosstalk-input .checkbox+.checkbox{margin-top:-5px}.crosstalk-input .checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.crosstalk-input .checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px} 2 | -------------------------------------------------------------------------------- /_freeze/site_libs/crosstalk-1.2.0/scss/crosstalk.scss: -------------------------------------------------------------------------------- 1 | /* Adjust margins outwards, so column contents line up with the edges of the 2 | parent of container-fluid. */ 3 | .container-fluid.crosstalk-bscols { 4 | margin-left: -30px; 5 | margin-right: -30px; 6 | white-space: normal; 7 | } 8 | 9 | /* But don't adjust the margins outwards if we're directly under the body, 10 | i.e. we were the top-level of something at the console. */ 11 | body > .container-fluid.crosstalk-bscols { 12 | margin-left: auto; 13 | margin-right: auto; 14 | } 15 | 16 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 17 | display: inline-block; 18 | padding-right: 12px; 19 | vertical-align: top; 20 | } 21 | 22 | @media only screen and (max-width:480px) { 23 | .crosstalk-input-checkboxgroup .crosstalk-options-group .crosstalk-options-column { 24 | display: block; 25 | padding-right: inherit; 26 | } 27 | } 28 | 29 | /* Relevant BS3 styles to make filter_checkbox() look reasonable without Bootstrap */ 30 | .crosstalk-input { 31 | margin-bottom: 15px; /* a la .form-group */ 32 | .control-label { 33 | margin-bottom: 0; 34 | vertical-align: middle; 35 | } 36 | input[type="checkbox"] { 37 | margin: 4px 0 0; 38 | margin-top: 1px; 39 | line-height: normal; 40 | } 41 | .checkbox { 42 | position: relative; 43 | display: block; 44 | margin-top: 10px; 45 | margin-bottom: 10px; 46 | } 47 | .checkbox > label{ 48 | padding-left: 20px; 49 | margin-bottom: 0; 50 | font-weight: 400; 51 | cursor: pointer; 52 | } 53 | .checkbox input[type="checkbox"], 54 | .checkbox-inline input[type="checkbox"] { 55 | position: absolute; 56 | margin-top: 2px; 57 | margin-left: -20px; 58 | } 59 | .checkbox + .checkbox { 60 | margin-top: -5px; 61 | } 62 | .checkbox-inline { 63 | position: relative; 64 | display: inline-block; 65 | padding-left: 20px; 66 | margin-bottom: 0; 67 | font-weight: 400; 68 | vertical-align: middle; 69 | cursor: pointer; 70 | } 71 | .checkbox-inline + .checkbox-inline { 72 | margin-top: 0; 73 | margin-left: 10px; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /_freeze/site_libs/datatables-css-0.0.0/datatables-crosstalk.css: -------------------------------------------------------------------------------- 1 | .dt-crosstalk-fade { 2 | opacity: 0.2; 3 | } 4 | 5 | html body div.DTS div.dataTables_scrollBody { 6 | background: none; 7 | } 8 | 9 | 10 | /* 11 | Fix https://github.com/rstudio/DT/issues/563 12 | If the `table.display` is set to "block" (e.g., pkgdown), the browser will display 13 | datatable objects strangely. The search panel and the page buttons will still be 14 | in full-width but the table body will be "compact" and shorter. 15 | In therory, having this attributes will affect `dom="t"` 16 | with `display: block` users. But in reality, there should be no one. 17 | We may remove the below lines in the future if the upstream agree to have this there. 18 | See https://github.com/DataTables/DataTablesSrc/issues/160 19 | */ 20 | 21 | table.dataTable { 22 | display: table; 23 | } 24 | 25 | 26 | /* 27 | When DTOutput(fill = TRUE), it receives a .html-fill-item class (via htmltools::bindFillRole()), which effectively amounts to `flex: 1 1 auto`. That's mostly fine, but the case where `fillContainer=TRUE`+`height:auto`+`flex-basis:auto` and the container (e.g., a bslib::card()) doesn't have a defined height is a bit problematic since the table wants to fit the parent but the parent wants to fit the table, which results pretty small table height (maybe because there is a minimum height somewhere?). It seems better in this case to impose a 400px height default for the table, which we can do by setting `flex-basis` to 400px (the table is still allowed to grow/shrink when the container has an opinionated height). 28 | */ 29 | 30 | .html-fill-container > .html-fill-item.datatables { 31 | flex-basis: 400px; 32 | } 33 | -------------------------------------------------------------------------------- /_freeze/site_libs/dt-core-bootstrap-1.13.4/css/dataTables.bootstrap.extra.css: -------------------------------------------------------------------------------- 1 | table.dataTable th.dt-left, 2 | table.dataTable td.dt-left { 3 | text-align: left; 4 | } 5 | table.dataTable th.dt-center, 6 | table.dataTable td.dt-center, 7 | table.dataTable td.dataTables_empty { 8 | text-align: center; 9 | } 10 | table.dataTable th.dt-right, 11 | table.dataTable td.dt-right { 12 | text-align: right; 13 | } 14 | table.dataTable th.dt-justify, 15 | table.dataTable td.dt-justify { 16 | text-align: justify; 17 | } 18 | table.dataTable th.dt-nowrap, 19 | table.dataTable td.dt-nowrap { 20 | white-space: nowrap; 21 | } 22 | table.dataTable thead th.dt-head-left, 23 | table.dataTable thead td.dt-head-left, 24 | table.dataTable tfoot th.dt-head-left, 25 | table.dataTable tfoot td.dt-head-left { 26 | text-align: left; 27 | } 28 | table.dataTable thead th.dt-head-center, 29 | table.dataTable thead td.dt-head-center, 30 | table.dataTable tfoot th.dt-head-center, 31 | table.dataTable tfoot td.dt-head-center { 32 | text-align: center; 33 | } 34 | table.dataTable thead th.dt-head-right, 35 | table.dataTable thead td.dt-head-right, 36 | table.dataTable tfoot th.dt-head-right, 37 | table.dataTable tfoot td.dt-head-right { 38 | text-align: right; 39 | } 40 | table.dataTable thead th.dt-head-justify, 41 | table.dataTable thead td.dt-head-justify, 42 | table.dataTable tfoot th.dt-head-justify, 43 | table.dataTable tfoot td.dt-head-justify { 44 | text-align: justify; 45 | } 46 | table.dataTable thead th.dt-head-nowrap, 47 | table.dataTable thead td.dt-head-nowrap, 48 | table.dataTable tfoot th.dt-head-nowrap, 49 | table.dataTable tfoot td.dt-head-nowrap { 50 | white-space: nowrap; 51 | } 52 | table.dataTable tbody th.dt-body-left, 53 | table.dataTable tbody td.dt-body-left { 54 | text-align: left; 55 | } 56 | table.dataTable tbody th.dt-body-center, 57 | table.dataTable tbody td.dt-body-center { 58 | text-align: center; 59 | } 60 | table.dataTable tbody th.dt-body-right, 61 | table.dataTable tbody td.dt-body-right { 62 | text-align: right; 63 | } 64 | table.dataTable tbody th.dt-body-justify, 65 | table.dataTable tbody td.dt-body-justify { 66 | text-align: justify; 67 | } 68 | table.dataTable tbody th.dt-body-nowrap, 69 | table.dataTable tbody td.dt-body-nowrap { 70 | white-space: nowrap; 71 | } 72 | .table.dataTable tbody td.active, .table.dataTable tbody tr.active td { 73 | background-color: #337ab7; 74 | color: white; 75 | } 76 | .dataTables_scrollBody .dataTables_sizing { 77 | visibility: hidden; 78 | } 79 | -------------------------------------------------------------------------------- /_freeze/site_libs/dt-core-bootstrap-1.13.4/js/dataTables.bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! DataTables Bootstrap 3 integration 2 | * ©2011-2015 SpryMedia Ltd - datatables.net/license 3 | */ 4 | !function(t){var n,i;"function"==typeof define&&define.amd?define(["jquery","datatables.net"],function(e){return t(e,window,document)}):"object"==typeof exports?(n=require("jquery"),i=function(e,a){a.fn.dataTable||require("datatables.net")(e,a)},"undefined"!=typeof window?module.exports=function(e,a){return e=e||window,a=a||n(e),i(e,a),t(a,0,e.document)}:(i(window,n),module.exports=t(n,window,window.document))):t(jQuery,window,document)}(function(x,e,n,i){"use strict";var r=x.fn.dataTable;return x.extend(!0,r.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"}),x.extend(r.ext.classes,{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"}),r.ext.renderer.pageButton.bootstrap=function(s,e,d,a,l,c){function u(e,a){for(var t,n,i=function(e){e.preventDefault(),x(e.currentTarget).hasClass("disabled")||b.page()==e.data.action||b.page(e.data.action).draw("page")},r=0,o=a.length;r",{class:m.sPageButton+" "+f,id:0===d&&"string"==typeof t?s.sTableId+"_"+t:null}).append(x("",{href:n?null:"#","aria-controls":s.sTableId,"aria-disabled":n?"true":null,"aria-label":w[t],"aria-role":"link","aria-current":"active"===f?"page":null,"data-dt-idx":t,tabindex:s.iTabIndex}).html(p)).appendTo(e),s.oApi._fnBindAction(n,{action:t},i))}}var p,f,t,b=new r.Api(s),m=s.oClasses,g=s.oLanguage.oPaginate,w=s.oLanguage.oAria.paginate||{};try{t=x(e).find(n.activeElement).data("dt-idx")}catch(e){}u(x(e).empty().html('