├── .gitignore ├── R ├── render.R └── setup-package.R ├── README.md ├── data ├── faketucky-codebook.txt └── faketucky.csv ├── exercises.R ├── getting-started.Rproj ├── index.html ├── slides ├── images │ ├── assignment-operator.png │ ├── code-chunk.png │ ├── data.jpg │ ├── download-course-project.jpeg │ ├── download-r.png │ ├── download-rstudio.png │ ├── engine-dashboard.png │ ├── files.jpg │ ├── function.jpg │ ├── glasses.jpeg │ ├── help.jpeg │ ├── installation.jpeg │ ├── issues.jpeg │ ├── missing-data.png │ ├── new-script.gif │ ├── non-numeric.png │ ├── object-function.png │ ├── packages.jpg │ ├── phone-apps.png │ ├── programming-google.png │ ├── projects.jpeg │ ├── r-console.png │ ├── r4ds-website.png │ ├── rstats-twitter.gif │ ├── rstudio-panes-highlight-environment.png │ ├── rstudio-panes.png │ ├── rstudio-screenshot.png │ ├── run-code.gif │ ├── skimr-vignette.gif │ ├── skimr.png │ ├── tidyverse-website.gif │ └── tidyverse.png ├── libs │ ├── pagedtable-1.1 │ │ ├── css │ │ │ └── pagedtable.css │ │ └── js │ │ │ └── pagedtable.js │ └── remark-css-0.0.1 │ │ └── default.css ├── setup.Rmd ├── slides.Rmd ├── slides.html ├── slides.pdf └── style.css └── solutions.R /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | Icon? -------------------------------------------------------------------------------- /R/render.R: -------------------------------------------------------------------------------- 1 | library(webshot) 2 | library(xaringan) 3 | library(here) 4 | library(rmarkdown) 5 | 6 | # Render presentation ----------------------------------------------------- 7 | 8 | # render(input = here("slides", "slides.Rmd"), 9 | # output_dir = here("slides"), 10 | # output_file = "slides.html", 11 | # clean = T) 12 | 13 | # Convert to PDF ---------------------------------------------------------- 14 | 15 | https://github.com/yihui/xaringan/wiki/Export-Slides-to-PDF 16 | 17 | webshot(here("slides", "slides.html"), 18 | here("slides", "slides.pdf")) 19 | 20 | -------------------------------------------------------------------------------- /R/setup-package.R: -------------------------------------------------------------------------------- 1 | library(tidyverse) 2 | library(here) 3 | 4 | # This file brings in assets (data, codebook, setup.Rmd and CSS) from the course assets repo (https://github.com/rfortherestofus/course-assets). 5 | 6 | # Get Data ---------------------------------------------------------------- 7 | 8 | download.file("https://github.com/rfortherestofus/course-assets/raw/master/data/faketucky-clean-names.csv", 9 | destfile = here("data", "faketucky.csv")) 10 | 11 | 12 | # Get Codebook ------------------------------------------------------------ 13 | 14 | download.file("https://raw.githubusercontent.com/rfortherestofus/course-assets/master/data/faketucky-codebook.txt", 15 | destfile = here("data", "faketucky-codebook.txt")) 16 | 17 | # Get setup.Rmd ----------------------------------------------------------- 18 | 19 | download.file("https://github.com/rfortherestofus/course-assets/raw/master/misc/setup.Rmd", 20 | destfile = here("slides", "setup.Rmd")) 21 | 22 | # Get CSS ----------------------------------------------------------------- 23 | 24 | download.file("https://raw.githubusercontent.com/rfortherestofus/course-assets/master/style/style.css", 25 | destfile = here("slides", "style.css")) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started With R 2 | 3 | One of the main obstacles that many new R users face is simply getting started. 4 | 5 | Some users struggle to figure out what the nuts and bolts of getting started: what do you need to download (wait, there’s R and RStudio?), where do you enter code, etc. 6 | 7 | Others become overwhelmed, in a classic example of the paradox of choice, with all of the resources available online for learning R. How do you know which approach to using R (and there are many!) is best? 8 | 9 | This free Getting Started with R course is designed to get new users, no matter what’s holding you back, up and running quickly. It takes you step-by-step, helping you download exactly what you need to get started. 10 | 11 | This course uses a [Tidyverse-centric approach](http://varianceexplained.org/r/teach-tidyverse/) that makes the learning process much easier (it’s also [favored by experienced users](https://twitter.com/rfortherest/status/1095375761660395520)). 12 | 13 | For more info, visit the [R for the Rest of Us website](https://rfortherestofus.com/courses/getting-started/). -------------------------------------------------------------------------------- /data/faketucky-codebook.txt: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------------------------------------- 2 | This is a modified version of the Faketucky code because I used a selection of variables and renamed them. 3 | 4 | Note that versions of the dataset use for R for the Rest of Us courses will have a different number of values (because, for example, only a single cohort will be included). I have also done some recoding (e.g. making missing values into 999 for) and renaming of variables for teaching purposes. 5 | 6 | The original codebook can be found here: https://github.com/OpenSDP/faketucky/blob/master/faketucky_codebook.txt 7 | 8 | --------------------------------------------------------------------------------------------------------------- 9 | student_id Random Student ID (Synthetic Data) 10 | --------------------------------------------------------------------------------------------------------------- 11 | 12 | type: numeric (long) 13 | 14 | range: [1,111991] units: 1 15 | unique values: 111,991 missing .: 0/111,991 16 | 17 | mean: 55996 18 | std. dev: 32329.2 19 | 20 | percentiles: 10% 25% 50% 75% 90% 21 | 11200 27998 55996 83994 10079 22 | 23 | 24 | --------------------------------------------------------------------------------------------------------------- 25 | first_hs_name Name of first high school attended 26 | --------------------------------------------------------------------------------------------------------------- 27 | 28 | type: string (str14) 29 | 30 | unique values: 403 missing "": 0/111,991 31 | 32 | examples: "Daisy Hill" 33 | "Hawthorne" 34 | "Marlowe" 35 | "Sandy Beach" 36 | 37 | warning: variable has embedded and trailing blanks 38 | 39 | 40 | --------------------------------------------------------------------------------------------------------------- 41 | school_district Name of first district attended in high school 42 | --------------------------------------------------------------------------------------------------------------- 43 | 44 | type: string (str13) 45 | 46 | unique values: 171 missing "": 0/111,991 47 | 48 | examples: "Fletcher" 49 | "Milton North" 50 | "Quigley" 51 | "Snowy Hill" 52 | 53 | warning: variable has embedded blanks 54 | 55 | --------------------------------------------------------------------------------------------------------------- 56 | male Male indicator 57 | --------------------------------------------------------------------------------------------------------------- 58 | 59 | type: numeric (byte) 60 | 61 | range: [0,1] units: 1 62 | unique values: 2 missing .: 19/111,991 63 | 64 | tabulation: Freq. Value 65 | 53,930 0 66 | 58,042 1 67 | 19 . 68 | 69 | --------------------------------------------------------------------------------------------------------------- 70 | race_ethnicity Student's race/ethnicity 71 | --------------------------------------------------------------------------------------------------------------- 72 | 73 | type: string (str24) 74 | 75 | unique values: 5 missing "": 1,303/111,991 76 | 77 | tabulation: Freq. Value 78 | 1,303 "" 79 | 13,464 "African-American" 80 | 1,548 "Asian/Pacific Islander" 81 | 3,742 "Hispanic" 82 | 1,903 "Multiple/Native American" 83 | 90,031 "White" 84 | 85 | warning: variable has embedded blanks 86 | 87 | --------------------------------------------------------------------------------------------------------------- 88 | free_and_reduced_lunch Student ever received free or reduced price lunch in high school 89 | --------------------------------------------------------------------------------------------------------------- 90 | 91 | type: numeric (byte) 92 | 93 | range: [0,1] units: 1 94 | unique values: 2 missing .: 1,415/111,991 95 | 96 | tabulation: Freq. Value 97 | 43,618 0 98 | 66,958 1 99 | 1,415 . 100 | 101 | --------------------------------------------------------------------------------------------------------------- 102 | percent_absent Percent of days enrolled in HS the student was absent (not excused) 103 | --------------------------------------------------------------------------------------------------------------- 104 | 105 | type: numeric (double) 106 | 107 | range: [0,3153] units: 1.000e-10 108 | unique values: 63,869 missing .: 222/111,991 109 | 110 | mean: 8.54899 111 | std. dev: 12.7716 112 | 113 | percentiles: 10% 25% 50% 75% 90% 114 | 1.53061 3.23988 6.18302 11.089 18.2446 115 | 116 | --------------------------------------------------------------------------------------------------------------- 117 | gpa GPA throughout high school 118 | --------------------------------------------------------------------------------------------------------------- 119 | 120 | type: numeric (double) 121 | 122 | range: [0,4] units: 1.000e-09 123 | unique values: 33,479 missing .: 3,746/111,991 124 | 125 | mean: 2.62661 126 | std. dev: .854065 127 | 128 | percentiles: 10% 25% 50% 75% 90% 129 | 1.4845 2.036 2.6845 3.3048 3.732 130 | 131 | 132 | --------------------------------------------------------------------------------------------------------------- 133 | act_reading_score Scaled score of highest reading ACT 134 | --------------------------------------------------------------------------------------------------------------- 135 | 136 | type: numeric (byte) 137 | 138 | range: [2,36] units: 1 139 | unique values: 35 missing .: 25,893/111,991 140 | 141 | mean: 19.9479 142 | std. dev: 6.02919 143 | 144 | percentiles: 10% 25% 50% 75% 90% 145 | 12 15 19 24 29 146 | 147 | 148 | --------------------------------------------------------------------------------------------------------------- 149 | act_math_score Scaled score of highest math ACT 150 | --------------------------------------------------------------------------------------------------------------- 151 | 152 | type: numeric (byte) 153 | 154 | range: [1,36] units: 1 155 | unique values: 32 missing .: 25,870/111,991 156 | 157 | mean: 19.1671 158 | std. dev: 4.71455 159 | 160 | percentiles: 10% 25% 50% 75% 90% 161 | 15 16 18 22 26 162 | 163 | --------------------------------------------------------------------------------------------------------------- 164 | received_hs_diploma Student received high school diploma 165 | --------------------------------------------------------------------------------------------------------------- 166 | 167 | type: numeric (byte) 168 | 169 | range: [0,1] units: 1 170 | unique values: 2 missing .: 0/111,991 171 | 172 | tabulation: Freq. Value 173 | 26,870 0 174 | 85,121 1 175 | 176 | --------------------------------------------------------------------------------------------------------------- 177 | enrolled_in_college Student was enrolled in any college Oct 1 following HS graduation 178 | --------------------------------------------------------------------------------------------------------------- 179 | 180 | type: numeric (byte) 181 | 182 | range: [0,1] units: 1 183 | unique values: 2 missing .: 26,831/111,991 184 | 185 | tabulation: Freq. Value 186 | 40,718 0 187 | 44,442 1 188 | 26,831 . 189 | 190 | -------------------------------------------------------------------------------- /exercises.R: -------------------------------------------------------------------------------- 1 | 2 | # Install Packages -------------------------------------------------------- 3 | 4 | # Install the tidyverse and skimr packages using the install.packages function 5 | 6 | 7 | # Load Packages ----------------------------------------------------------- 8 | 9 | # Load the tidyverse and skimr packages using the library function 10 | 11 | 12 | # Import Data ------------------------------------------------------------- 13 | 14 | # Import the faketucky data into a data frame called faketucky. 15 | 16 | # Examine Data ------------------------------------------------------------ 17 | 18 | # Enter the name of your data frame (faketucky) and run it as code to see the output. 19 | 20 | 21 | # Use head() to see the first 10 rows of faketucky. 22 | 23 | 24 | # Use tail() to see the last 20 rows of faketucky. 25 | 26 | 27 | # Open faketucky by clicking on it in the environment/history pane or by using the View() function. 28 | 29 | 30 | # Use the skim() function to examine faketucky. 31 | 32 | 33 | skim(mtcars) 34 | -------------------------------------------------------------------------------- /getting-started.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 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /slides/images/assignment-operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/assignment-operator.png -------------------------------------------------------------------------------- /slides/images/code-chunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/code-chunk.png -------------------------------------------------------------------------------- /slides/images/data.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/data.jpg -------------------------------------------------------------------------------- /slides/images/download-course-project.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/download-course-project.jpeg -------------------------------------------------------------------------------- /slides/images/download-r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/download-r.png -------------------------------------------------------------------------------- /slides/images/download-rstudio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/download-rstudio.png -------------------------------------------------------------------------------- /slides/images/engine-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/engine-dashboard.png -------------------------------------------------------------------------------- /slides/images/files.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/files.jpg -------------------------------------------------------------------------------- /slides/images/function.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/function.jpg -------------------------------------------------------------------------------- /slides/images/glasses.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/glasses.jpeg -------------------------------------------------------------------------------- /slides/images/help.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/help.jpeg -------------------------------------------------------------------------------- /slides/images/installation.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/installation.jpeg -------------------------------------------------------------------------------- /slides/images/issues.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/issues.jpeg -------------------------------------------------------------------------------- /slides/images/missing-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/missing-data.png -------------------------------------------------------------------------------- /slides/images/new-script.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/new-script.gif -------------------------------------------------------------------------------- /slides/images/non-numeric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/non-numeric.png -------------------------------------------------------------------------------- /slides/images/object-function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/object-function.png -------------------------------------------------------------------------------- /slides/images/packages.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/packages.jpg -------------------------------------------------------------------------------- /slides/images/phone-apps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/phone-apps.png -------------------------------------------------------------------------------- /slides/images/programming-google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/programming-google.png -------------------------------------------------------------------------------- /slides/images/projects.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/projects.jpeg -------------------------------------------------------------------------------- /slides/images/r-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/r-console.png -------------------------------------------------------------------------------- /slides/images/r4ds-website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/r4ds-website.png -------------------------------------------------------------------------------- /slides/images/rstats-twitter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/rstats-twitter.gif -------------------------------------------------------------------------------- /slides/images/rstudio-panes-highlight-environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/rstudio-panes-highlight-environment.png -------------------------------------------------------------------------------- /slides/images/rstudio-panes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/rstudio-panes.png -------------------------------------------------------------------------------- /slides/images/rstudio-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/rstudio-screenshot.png -------------------------------------------------------------------------------- /slides/images/run-code.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/run-code.gif -------------------------------------------------------------------------------- /slides/images/skimr-vignette.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/skimr-vignette.gif -------------------------------------------------------------------------------- /slides/images/skimr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/skimr.png -------------------------------------------------------------------------------- /slides/images/tidyverse-website.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/tidyverse-website.gif -------------------------------------------------------------------------------- /slides/images/tidyverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rfortherestofus/getting-started/0a6d304945df2fa4107e927a04f65f8928458dcf/slides/images/tidyverse.png -------------------------------------------------------------------------------- /slides/libs/pagedtable-1.1/css/pagedtable.css: -------------------------------------------------------------------------------- 1 | .pagedtable { 2 | overflow: auto; 3 | padding-left: 8px; 4 | padding-right: 8px; 5 | } 6 | 7 | .pagedtable-wrapper { 8 | border: 1px solid #ccc; 9 | border-radius: 4px; 10 | margin-bottom: 10px; 11 | } 12 | 13 | .pagedtable table { 14 | width: 100%; 15 | max-width: 100%; 16 | margin: 0; 17 | } 18 | 19 | .pagedtable th { 20 | padding: 0 5px 0 5px; 21 | border: none; 22 | border-bottom: 2px solid #dddddd; 23 | 24 | min-width: 45px; 25 | } 26 | 27 | .pagedtable-empty th { 28 | display: none; 29 | } 30 | 31 | .pagedtable td { 32 | padding: 0 4px 0 4px; 33 | } 34 | 35 | .pagedtable .even { 36 | background-color: rgba(140, 140, 140, 0.1); 37 | } 38 | 39 | .pagedtable-padding-col { 40 | display: none; 41 | } 42 | 43 | .pagedtable a { 44 | -webkit-touch-callout: none; 45 | -webkit-user-select: none; 46 | -khtml-user-select: none; 47 | -moz-user-select: none; 48 | -ms-user-select: none; 49 | user-select: none; 50 | } 51 | 52 | .pagedtable-index-nav { 53 | cursor: pointer; 54 | padding: 0 5px 0 5px; 55 | float: right; 56 | border: 0; 57 | } 58 | 59 | .pagedtable-index-nav-disabled { 60 | cursor: default; 61 | text-decoration: none; 62 | color: #999; 63 | } 64 | 65 | a.pagedtable-index-nav-disabled:hover { 66 | text-decoration: none; 67 | color: #999; 68 | } 69 | 70 | .pagedtable-indexes { 71 | cursor: pointer; 72 | float: right; 73 | border: 0; 74 | } 75 | 76 | .pagedtable-index-current { 77 | cursor: default; 78 | text-decoration: none; 79 | font-weight: bold; 80 | color: #333; 81 | border: 0; 82 | } 83 | 84 | a.pagedtable-index-current:hover { 85 | text-decoration: none; 86 | font-weight: bold; 87 | color: #333; 88 | } 89 | 90 | .pagedtable-index { 91 | width: 30px; 92 | display: inline-block; 93 | text-align: center; 94 | border: 0; 95 | } 96 | 97 | .pagedtable-index-separator-left { 98 | display: inline-block; 99 | color: #333; 100 | font-size: 9px; 101 | padding: 0 0 0 0; 102 | cursor: default; 103 | } 104 | 105 | .pagedtable-index-separator-right { 106 | display: inline-block; 107 | color: #333; 108 | font-size: 9px; 109 | padding: 0 4px 0 0; 110 | cursor: default; 111 | } 112 | 113 | .pagedtable-footer { 114 | padding-top: 4px; 115 | padding-bottom: 5px; 116 | } 117 | 118 | .pagedtable-not-empty .pagedtable-footer { 119 | border-top: 2px solid #dddddd; 120 | } 121 | 122 | .pagedtable-info { 123 | overflow: hidden; 124 | color: #999; 125 | white-space: nowrap; 126 | text-overflow: ellipsis; 127 | } 128 | 129 | .pagedtable-header-name { 130 | overflow: hidden; 131 | text-overflow: ellipsis; 132 | } 133 | 134 | .pagedtable-header-type { 135 | color: #999; 136 | font-weight: 400; 137 | } 138 | 139 | .pagedtable-na-cell { 140 | font-style: italic; 141 | opacity: 0.3; 142 | } 143 | -------------------------------------------------------------------------------- /slides/libs/pagedtable-1.1/js/pagedtable.js: -------------------------------------------------------------------------------- 1 | // Production steps of ECMA-262, Edition 5, 15.4.4.18 2 | // Reference: http://es5.github.io/#x15.4.4.18 3 | if (!Array.prototype.forEach) { 4 | 5 | Array.prototype.forEach = function(callback, thisArg) { 6 | 7 | var T, k; 8 | 9 | if (this === null) { 10 | throw new TypeError(' this is null or not defined'); 11 | } 12 | 13 | // 1. Let O be the result of calling toObject() passing the 14 | // |this| value as the argument. 15 | var O = Object(this); 16 | 17 | // 2. Let lenValue be the result of calling the Get() internal 18 | // method of O with the argument "length". 19 | // 3. Let len be toUint32(lenValue). 20 | var len = O.length >>> 0; 21 | 22 | // 4. If isCallable(callback) is false, throw a TypeError exception. 23 | // See: http://es5.github.com/#x9.11 24 | if (typeof callback !== "function") { 25 | throw new TypeError(callback + ' is not a function'); 26 | } 27 | 28 | // 5. If thisArg was supplied, let T be thisArg; else let 29 | // T be undefined. 30 | if (arguments.length > 1) { 31 | T = thisArg; 32 | } 33 | 34 | // 6. Let k be 0 35 | k = 0; 36 | 37 | // 7. Repeat, while k < len 38 | while (k < len) { 39 | 40 | var kValue; 41 | 42 | // a. Let Pk be ToString(k). 43 | // This is implicit for LHS operands of the in operator 44 | // b. Let kPresent be the result of calling the HasProperty 45 | // internal method of O with argument Pk. 46 | // This step can be combined with c 47 | // c. If kPresent is true, then 48 | if (k in O) { 49 | 50 | // i. Let kValue be the result of calling the Get internal 51 | // method of O with argument Pk. 52 | kValue = O[k]; 53 | 54 | // ii. Call the Call internal method of callback with T as 55 | // the this value and argument list containing kValue, k, and O. 56 | callback.call(T, kValue, k, O); 57 | } 58 | // d. Increase k by 1. 59 | k++; 60 | } 61 | // 8. return undefined 62 | }; 63 | } 64 | 65 | // Production steps of ECMA-262, Edition 5, 15.4.4.19 66 | // Reference: http://es5.github.io/#x15.4.4.19 67 | if (!Array.prototype.map) { 68 | 69 | Array.prototype.map = function(callback, thisArg) { 70 | 71 | var T, A, k; 72 | 73 | if (this == null) { 74 | throw new TypeError(' this is null or not defined'); 75 | } 76 | 77 | // 1. Let O be the result of calling ToObject passing the |this| 78 | // value as the argument. 79 | var O = Object(this); 80 | 81 | // 2. Let lenValue be the result of calling the Get internal 82 | // method of O with the argument "length". 83 | // 3. Let len be ToUint32(lenValue). 84 | var len = O.length >>> 0; 85 | 86 | // 4. If IsCallable(callback) is false, throw a TypeError exception. 87 | // See: http://es5.github.com/#x9.11 88 | if (typeof callback !== 'function') { 89 | throw new TypeError(callback + ' is not a function'); 90 | } 91 | 92 | // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. 93 | if (arguments.length > 1) { 94 | T = thisArg; 95 | } 96 | 97 | // 6. Let A be a new array created as if by the expression new Array(len) 98 | // where Array is the standard built-in constructor with that name and 99 | // len is the value of len. 100 | A = new Array(len); 101 | 102 | // 7. Let k be 0 103 | k = 0; 104 | 105 | // 8. Repeat, while k < len 106 | while (k < len) { 107 | 108 | var kValue, mappedValue; 109 | 110 | // a. Let Pk be ToString(k). 111 | // This is implicit for LHS operands of the in operator 112 | // b. Let kPresent be the result of calling the HasProperty internal 113 | // method of O with argument Pk. 114 | // This step can be combined with c 115 | // c. If kPresent is true, then 116 | if (k in O) { 117 | 118 | // i. Let kValue be the result of calling the Get internal 119 | // method of O with argument Pk. 120 | kValue = O[k]; 121 | 122 | // ii. Let mappedValue be the result of calling the Call internal 123 | // method of callback with T as the this value and argument 124 | // list containing kValue, k, and O. 125 | mappedValue = callback.call(T, kValue, k, O); 126 | 127 | // iii. Call the DefineOwnProperty internal method of A with arguments 128 | // Pk, Property Descriptor 129 | // { Value: mappedValue, 130 | // Writable: true, 131 | // Enumerable: true, 132 | // Configurable: true }, 133 | // and false. 134 | 135 | // In browsers that support Object.defineProperty, use the following: 136 | // Object.defineProperty(A, k, { 137 | // value: mappedValue, 138 | // writable: true, 139 | // enumerable: true, 140 | // configurable: true 141 | // }); 142 | 143 | // For best browser support, use the following: 144 | A[k] = mappedValue; 145 | } 146 | // d. Increase k by 1. 147 | k++; 148 | } 149 | 150 | // 9. return A 151 | return A; 152 | }; 153 | } 154 | 155 | var PagedTable = function (pagedTable) { 156 | var me = this; 157 | 158 | var source = function(pagedTable) { 159 | var sourceElems = [].slice.call(pagedTable.children).filter(function(e) { 160 | return e.hasAttribute("data-pagedtable-source"); 161 | }); 162 | 163 | if (sourceElems === null || sourceElems.length !== 1) { 164 | throw("A single data-pagedtable-source was not found"); 165 | } 166 | 167 | return JSON.parse(sourceElems[0].innerHTML); 168 | }(pagedTable); 169 | 170 | var options = function(source) { 171 | var options = typeof(source.options) !== "undefined" && 172 | source.options !== null ? source.options : {}; 173 | 174 | var columns = typeof(options.columns) !== "undefined" ? options.columns : {}; 175 | var rows = typeof(options.rows) !== "undefined" ? options.rows : {}; 176 | 177 | var positiveIntOrNull = function(value) { 178 | return parseInt(value) >= 0 ? parseInt(value) : null; 179 | }; 180 | 181 | return { 182 | pages: positiveIntOrNull(options.pages), 183 | rows: { 184 | min: positiveIntOrNull(rows.min), 185 | max: positiveIntOrNull(rows.max), 186 | total: positiveIntOrNull(rows.total) 187 | }, 188 | columns: { 189 | min: positiveIntOrNull(columns.min), 190 | max: positiveIntOrNull(columns.max), 191 | total: positiveIntOrNull(columns.total) 192 | } 193 | }; 194 | }(source); 195 | 196 | var Measurer = function() { 197 | 198 | // set some default initial values that will get adjusted in runtime 199 | me.measures = { 200 | padding: 12, 201 | character: 8, 202 | height: 15, 203 | defaults: true 204 | }; 205 | 206 | me.calculate = function(measuresCell) { 207 | if (!me.measures.defaults) 208 | return; 209 | 210 | var measuresCellStyle = window.getComputedStyle(measuresCell, null); 211 | 212 | var newPadding = parsePadding(measuresCellStyle.paddingLeft) + 213 | parsePadding(measuresCellStyle.paddingRight); 214 | 215 | var sampleString = "ABCDEFGHIJ0123456789"; 216 | var newCharacter = Math.ceil(measuresCell.clientWidth / sampleString.length); 217 | 218 | if (newPadding <= 0 || newCharacter <= 0) 219 | return; 220 | 221 | me.measures.padding = newPadding; 222 | me.measures.character = newCharacter; 223 | me.measures.height = measuresCell.clientHeight; 224 | me.measures.defaults = false; 225 | }; 226 | 227 | return me; 228 | }; 229 | 230 | var Page = function(data, options) { 231 | var me = this; 232 | 233 | var defaults = { 234 | max: 7, 235 | rows: 10 236 | }; 237 | 238 | var totalPages = function() { 239 | return Math.ceil(data.length / me.rows); 240 | }; 241 | 242 | me.number = 0; 243 | me.max = options.pages !== null ? options.pages : defaults.max; 244 | me.visible = me.max; 245 | me.rows = options.rows.min !== null ? options.rows.min : defaults.rows; 246 | me.total = totalPages(); 247 | 248 | me.setRows = function(newRows) { 249 | me.rows = newRows; 250 | me.total = totalPages(); 251 | }; 252 | 253 | me.setPageNumber = function(newPageNumber) { 254 | if (newPageNumber < 0) newPageNumber = 0; 255 | if (newPageNumber >= me.total) newPageNumber = me.total - 1; 256 | 257 | me.number = newPageNumber; 258 | }; 259 | 260 | me.setVisiblePages = function(visiblePages) { 261 | me.visible = Math.min(me.max, visiblePages); 262 | me.setPageNumber(me.number); 263 | }; 264 | 265 | me.getVisiblePageRange = function() { 266 | var start = me.number - Math.max(Math.floor((me.visible - 1) / 2), 0); 267 | var end = me.number + Math.floor(me.visible / 2) + 1; 268 | var pageCount = me.total; 269 | 270 | if (start < 0) { 271 | var diffToStart = 0 - start; 272 | start += diffToStart; 273 | end += diffToStart; 274 | } 275 | 276 | if (end > pageCount) { 277 | var diffToEnd = end - pageCount; 278 | start -= diffToEnd; 279 | end -= diffToEnd; 280 | } 281 | 282 | start = start < 0 ? 0 : start; 283 | end = end >= pageCount ? pageCount : end; 284 | 285 | var first = false; 286 | var last = false; 287 | 288 | if (start > 0 && me.visible > 1) { 289 | start = start + 1; 290 | first = true; 291 | } 292 | 293 | if (end < pageCount && me.visible > 2) { 294 | end = end - 1; 295 | last = true; 296 | } 297 | 298 | return { 299 | first: first, 300 | start: start, 301 | end: end, 302 | last: last 303 | }; 304 | }; 305 | 306 | me.getRowStart = function() { 307 | var rowStart = page.number * page.rows; 308 | if (rowStart < 0) 309 | rowStart = 0; 310 | 311 | return rowStart; 312 | }; 313 | 314 | me.getRowEnd = function() { 315 | var rowStart = me.getRowStart(); 316 | return Math.min(rowStart + me.rows, data.length); 317 | }; 318 | 319 | me.getPaddingRows = function() { 320 | var rowStart = me.getRowStart(); 321 | var rowEnd = me.getRowEnd(); 322 | return data.length > me.rows ? me.rows - (rowEnd - rowStart) : 0; 323 | }; 324 | }; 325 | 326 | var Columns = function(data, columns, options) { 327 | var me = this; 328 | 329 | me.defaults = { 330 | min: 5 331 | }; 332 | 333 | me.number = 0; 334 | me.visible = 0; 335 | me.total = columns.length; 336 | me.subset = []; 337 | me.padding = 0; 338 | me.min = options.columns.min !== null ? options.columns.min : me.defaults.min; 339 | me.max = options.columns.max !== null ? options.columns.max : null; 340 | me.widths = {}; 341 | 342 | var widthsLookAhead = Math.max(100, options.rows.min); 343 | var paddingColChars = 10; 344 | 345 | me.emptyNames = function() { 346 | columns.forEach(function(column) { 347 | if (columns.label !== null && columns.label !== "") 348 | return false; 349 | }); 350 | 351 | return true; 352 | }; 353 | 354 | var parsePadding = function(value) { 355 | return parseInt(value) >= 0 ? parseInt(value) : 0; 356 | }; 357 | 358 | me.calculateWidths = function(measures) { 359 | columns.forEach(function(column) { 360 | var maxChars = Math.max( 361 | column.label.toString().length, 362 | column.type.toString().length 363 | ); 364 | 365 | for (var idxRow = 0; idxRow < Math.min(widthsLookAhead, data.length); idxRow++) { 366 | maxChars = Math.max(maxChars, data[idxRow][column.name.toString()].length); 367 | } 368 | 369 | me.widths[column.name] = { 370 | // width in characters 371 | chars: maxChars, 372 | // width for the inner html columns 373 | inner: maxChars * measures.character, 374 | // width adding outer styles like padding 375 | outer: maxChars * measures.character + measures.padding 376 | }; 377 | }); 378 | }; 379 | 380 | me.getWidth = function() { 381 | var widthOuter = 0; 382 | for (var idxCol = 0; idxCol < me.subset.length; idxCol++) { 383 | var columnName = me.subset[idxCol].name; 384 | widthOuter = widthOuter + me.widths[columnName].outer; 385 | } 386 | 387 | widthOuter = widthOuter + me.padding * paddingColChars * measurer.measures.character; 388 | 389 | if (me.hasMoreLeftColumns()) { 390 | widthOuter = widthOuter + columnNavigationWidthPX + measurer.measures.padding; 391 | } 392 | 393 | if (me.hasMoreRightColumns()) { 394 | widthOuter = widthOuter + columnNavigationWidthPX + measurer.measures.padding; 395 | } 396 | 397 | return widthOuter; 398 | }; 399 | 400 | me.updateSlice = function() { 401 | if (me.number + me.visible >= me.total) 402 | me.number = me.total - me.visible; 403 | 404 | if (me.number < 0) me.number = 0; 405 | 406 | me.subset = columns.slice(me.number, Math.min(me.number + me.visible, me.total)); 407 | 408 | me.subset = me.subset.map(function(column) { 409 | Object.keys(column).forEach(function(colKey) { 410 | column[colKey] = column[colKey] === null ? "" : column[colKey].toString(); 411 | }); 412 | 413 | column.width = null; 414 | return column; 415 | }); 416 | }; 417 | 418 | me.setVisibleColumns = function(columnNumber, newVisibleColumns, paddingCount) { 419 | me.number = columnNumber; 420 | me.visible = newVisibleColumns; 421 | me.padding = paddingCount; 422 | 423 | me.updateSlice(); 424 | }; 425 | 426 | me.incColumnNumber = function(increment) { 427 | me.number = me.number + increment; 428 | }; 429 | 430 | me.setColumnNumber = function(newNumber) { 431 | me.number = newNumber; 432 | }; 433 | 434 | me.setPaddingCount = function(newPadding) { 435 | me.padding = newPadding; 436 | }; 437 | 438 | me.getPaddingCount = function() { 439 | return me.padding; 440 | }; 441 | 442 | me.hasMoreLeftColumns = function() { 443 | return me.number > 0; 444 | }; 445 | 446 | me.hasMoreRightColumns = function() { 447 | return me.number + me.visible < me.total; 448 | }; 449 | 450 | me.updateSlice(0); 451 | return me; 452 | }; 453 | 454 | var data = source.data; 455 | var page = new Page(data, options); 456 | var measurer = new Measurer(data, options); 457 | var columns = new Columns(data, source.columns, options); 458 | 459 | var table = null; 460 | var tableDiv = null; 461 | var header = null; 462 | var footer = null; 463 | var tbody = null; 464 | 465 | // Caches pagedTable.clientWidth, specially for webkit 466 | var cachedPagedTableClientWidth = null; 467 | 468 | var onChangeCallbacks = []; 469 | 470 | var clearSelection = function() { 471 | if(document.selection && document.selection.empty) { 472 | document.selection.empty(); 473 | } else if(window.getSelection) { 474 | var sel = window.getSelection(); 475 | sel.removeAllRanges(); 476 | } 477 | }; 478 | 479 | var columnNavigationWidthPX = 5; 480 | 481 | var renderColumnNavigation = function(increment, backwards) { 482 | var arrow = document.createElement("div"); 483 | arrow.setAttribute("style", 484 | "border-top: " + columnNavigationWidthPX + "px solid transparent;" + 485 | "border-bottom: " + columnNavigationWidthPX + "px solid transparent;" + 486 | "border-" + (backwards ? "right" : "left") + ": " + columnNavigationWidthPX + "px solid;"); 487 | 488 | var header = document.createElement("th"); 489 | header.appendChild(arrow); 490 | header.setAttribute("style", 491 | "cursor: pointer;" + 492 | "vertical-align: middle;" + 493 | "min-width: " + columnNavigationWidthPX + "px;" + 494 | "width: " + columnNavigationWidthPX + "px;"); 495 | 496 | header.onclick = function() { 497 | columns.incColumnNumber(backwards ? -1 : increment); 498 | 499 | me.animateColumns(backwards); 500 | renderFooter(); 501 | 502 | clearSelection(); 503 | triggerOnChange(); 504 | }; 505 | 506 | return header; 507 | }; 508 | 509 | var maxColumnWidth = function(width) { 510 | var padding = 80; 511 | var columnMax = Math.max(cachedPagedTableClientWidth - padding, 0); 512 | 513 | return parseInt(width) > 0 ? 514 | Math.min(columnMax, parseInt(width)) + "px" : 515 | columnMax + "px"; 516 | }; 517 | 518 | var clearHeader = function() { 519 | var thead = pagedTable.querySelectorAll("thead")[0]; 520 | thead.innerHTML = ""; 521 | }; 522 | 523 | var renderHeader = function(clear) { 524 | cachedPagedTableClientWidth = pagedTable.clientWidth; 525 | 526 | var fragment = document.createDocumentFragment(); 527 | 528 | header = document.createElement("tr"); 529 | fragment.appendChild(header); 530 | 531 | if (columns.number > 0) 532 | header.appendChild(renderColumnNavigation(-columns.visible, true)); 533 | 534 | columns.subset = columns.subset.map(function(columnData) { 535 | var column = document.createElement("th"); 536 | column.setAttribute("align", columnData.align); 537 | column.style.textAlign = columnData.align; 538 | 539 | column.style.maxWidth = maxColumnWidth(null); 540 | if (columnData.width) { 541 | column.style.minWidth = 542 | column.style.maxWidth = maxColumnWidth(columnData.width); 543 | } 544 | 545 | var columnName = document.createElement("div"); 546 | columnName.setAttribute("class", "pagedtable-header-name"); 547 | if (columnData.label === "") { 548 | columnName.innerHTML = " "; 549 | } 550 | else { 551 | columnName.appendChild(document.createTextNode(columnData.label)); 552 | } 553 | column.appendChild(columnName); 554 | 555 | var columnType = document.createElement("div"); 556 | columnType.setAttribute("class", "pagedtable-header-type"); 557 | if (columnData.type === "") { 558 | columnType.innerHTML = " "; 559 | } 560 | else { 561 | columnType.appendChild(document.createTextNode("<" + columnData.type + ">")); 562 | } 563 | column.appendChild(columnType); 564 | 565 | header.appendChild(column); 566 | 567 | columnData.element = column; 568 | 569 | return columnData; 570 | }); 571 | 572 | for (var idx = 0; idx < columns.getPaddingCount(); idx++) { 573 | var paddingCol = document.createElement("th"); 574 | paddingCol.setAttribute("class", "pagedtable-padding-col"); 575 | header.appendChild(paddingCol); 576 | } 577 | 578 | if (columns.number + columns.visible < columns.total) 579 | header.appendChild(renderColumnNavigation(columns.visible, false)); 580 | 581 | if (typeof(clear) == "undefined" || clear) clearHeader(); 582 | var thead = pagedTable.querySelectorAll("thead")[0]; 583 | thead.appendChild(fragment); 584 | }; 585 | 586 | me.animateColumns = function(backwards) { 587 | var thead = pagedTable.querySelectorAll("thead")[0]; 588 | 589 | var headerOld = thead.querySelectorAll("tr")[0]; 590 | var tbodyOld = table.querySelectorAll("tbody")[0]; 591 | 592 | me.fitColumns(backwards); 593 | 594 | renderHeader(false); 595 | 596 | header.style.opacity = "0"; 597 | header.style.transform = backwards ? "translateX(-30px)" : "translateX(30px)"; 598 | header.style.transition = "transform 200ms linear, opacity 200ms"; 599 | header.style.transitionDelay = "0"; 600 | 601 | renderBody(false); 602 | 603 | if (headerOld) { 604 | headerOld.style.position = "absolute"; 605 | headerOld.style.transform = "translateX(0px)"; 606 | headerOld.style.opacity = "1"; 607 | headerOld.style.transition = "transform 100ms linear, opacity 100ms"; 608 | headerOld.setAttribute("class", "pagedtable-remove-head"); 609 | if (headerOld.style.transitionEnd) { 610 | headerOld.addEventListener("transitionend", function() { 611 | var headerOldByClass = thead.querySelector(".pagedtable-remove-head"); 612 | if (headerOldByClass) thead.removeChild(headerOldByClass); 613 | }); 614 | } 615 | else { 616 | thead.removeChild(headerOld); 617 | } 618 | } 619 | 620 | if (tbodyOld) table.removeChild(tbodyOld); 621 | 622 | tbody.style.opacity = "0"; 623 | tbody.style.transition = "transform 200ms linear, opacity 200ms"; 624 | tbody.style.transitionDelay = "0ms"; 625 | 626 | // force relayout 627 | window.getComputedStyle(header).opacity; 628 | window.getComputedStyle(tbody).opacity; 629 | 630 | if (headerOld) { 631 | headerOld.style.transform = backwards ? "translateX(20px)" : "translateX(-30px)"; 632 | headerOld.style.opacity = "0"; 633 | } 634 | 635 | header.style.transform = "translateX(0px)"; 636 | header.style.opacity = "1"; 637 | 638 | tbody.style.opacity = "1"; 639 | } 640 | 641 | me.onChange = function(callback) { 642 | onChangeCallbacks.push(callback); 643 | }; 644 | 645 | var triggerOnChange = function() { 646 | onChangeCallbacks.forEach(function(onChange) { 647 | onChange(); 648 | }); 649 | }; 650 | 651 | var clearBody = function() { 652 | if (tbody) { 653 | table.removeChild(tbody); 654 | tbody = null; 655 | } 656 | }; 657 | 658 | var renderBody = function(clear) { 659 | cachedPagedTableClientWidth = pagedTable.clientWidth 660 | 661 | var fragment = document.createDocumentFragment(); 662 | 663 | var pageData = data.slice(page.getRowStart(), page.getRowEnd()); 664 | 665 | pageData.forEach(function(dataRow, idxRow) { 666 | var htmlRow = document.createElement("tr"); 667 | htmlRow.setAttribute("class", (idxRow % 2 !==0) ? "even" : "odd"); 668 | 669 | if (columns.hasMoreLeftColumns()) 670 | htmlRow.appendChild(document.createElement("td")); 671 | 672 | columns.subset.forEach(function(columnData) { 673 | var cellName = columnData.name; 674 | var dataCell = dataRow[cellName]; 675 | var htmlCell = document.createElement("td"); 676 | 677 | if (dataCell === "NA") htmlCell.setAttribute("class", "pagedtable-na-cell"); 678 | if (dataCell === "__NA__") dataCell = "NA"; 679 | 680 | var cellText = document.createTextNode(dataCell); 681 | htmlCell.appendChild(cellText); 682 | if (dataCell.length > 50) { 683 | htmlCell.setAttribute("title", dataCell); 684 | } 685 | htmlCell.setAttribute("align", columnData.align); 686 | htmlCell.style.textAlign = columnData.align; 687 | htmlCell.style.maxWidth = maxColumnWidth(null); 688 | if (columnData.width) { 689 | htmlCell.style.minWidth = htmlCell.style.maxWidth = maxColumnWidth(columnData.width); 690 | } 691 | htmlRow.appendChild(htmlCell); 692 | }); 693 | 694 | for (var idx = 0; idx < columns.getPaddingCount(); idx++) { 695 | var paddingCol = document.createElement("td"); 696 | paddingCol.setAttribute("class", "pagedtable-padding-col"); 697 | htmlRow.appendChild(paddingCol); 698 | } 699 | 700 | if (columns.hasMoreRightColumns()) 701 | htmlRow.appendChild(document.createElement("td")); 702 | 703 | fragment.appendChild(htmlRow); 704 | }); 705 | 706 | for (var idxPadding = 0; idxPadding < page.getPaddingRows(); idxPadding++) { 707 | var paddingRow = document.createElement("tr"); 708 | 709 | var paddingCellRow = document.createElement("td"); 710 | paddingCellRow.innerHTML = " "; 711 | paddingCellRow.setAttribute("colspan", "100%"); 712 | paddingRow.appendChild(paddingCellRow); 713 | 714 | fragment.appendChild(paddingRow); 715 | } 716 | 717 | if (typeof(clear) == "undefined" || clear) clearBody(); 718 | tbody = document.createElement("tbody"); 719 | tbody.appendChild(fragment); 720 | 721 | table.appendChild(tbody); 722 | }; 723 | 724 | var getLabelInfo = function() { 725 | var pageStart = page.getRowStart(); 726 | var pageEnd = page.getRowEnd(); 727 | var totalRows = data.length; 728 | 729 | var totalRowsLabel = options.rows.total ? options.rows.total : totalRows; 730 | var totalRowsLabelFormat = totalRowsLabel.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,'); 731 | 732 | var infoText = (pageStart + 1) + "-" + pageEnd + " of " + totalRowsLabelFormat + " rows"; 733 | if (totalRows < page.rows) { 734 | infoText = totalRowsLabel + " row" + (totalRows != 1 ? "s" : ""); 735 | } 736 | if (columns.total > columns.visible) { 737 | var totalColumnsLabel = options.columns.total ? options.columns.total : columns.total; 738 | 739 | infoText = infoText + " | " + (columns.number + 1) + "-" + 740 | (Math.min(columns.number + columns.visible, columns.total)) + 741 | " of " + totalColumnsLabel + " columns"; 742 | } 743 | 744 | return infoText; 745 | }; 746 | 747 | var clearFooter = function() { 748 | footer = pagedTable.querySelectorAll("div.pagedtable-footer")[0]; 749 | footer.innerHTML = ""; 750 | 751 | return footer; 752 | }; 753 | 754 | var createPageLink = function(idxPage) { 755 | var pageLink = document.createElement("a"); 756 | pageLinkClass = idxPage === page.number ? "pagedtable-index pagedtable-index-current" : "pagedtable-index"; 757 | pageLink.setAttribute("class", pageLinkClass); 758 | pageLink.setAttribute("data-page-index", idxPage); 759 | pageLink.onclick = function() { 760 | page.setPageNumber(parseInt(this.getAttribute("data-page-index"))); 761 | renderBody(); 762 | renderFooter(); 763 | 764 | triggerOnChange(); 765 | }; 766 | 767 | pageLink.appendChild(document.createTextNode(idxPage + 1)); 768 | 769 | return pageLink; 770 | } 771 | 772 | var renderFooter = function() { 773 | footer = clearFooter(); 774 | 775 | var next = document.createElement("a"); 776 | next.appendChild(document.createTextNode("Next")); 777 | next.onclick = function() { 778 | page.setPageNumber(page.number + 1); 779 | renderBody(); 780 | renderFooter(); 781 | 782 | triggerOnChange(); 783 | }; 784 | if (data.length > page.rows) footer.appendChild(next); 785 | 786 | var pageNumbers = document.createElement("div"); 787 | pageNumbers.setAttribute("class", "pagedtable-indexes"); 788 | 789 | var pageRange = page.getVisiblePageRange(); 790 | 791 | if (pageRange.first) { 792 | var pageLink = createPageLink(0); 793 | pageNumbers.appendChild(pageLink); 794 | 795 | var pageSeparator = document.createElement("div"); 796 | pageSeparator.setAttribute("class", "pagedtable-index-separator-left"); 797 | pageSeparator.appendChild(document.createTextNode("...")) 798 | pageNumbers.appendChild(pageSeparator); 799 | } 800 | 801 | for (var idxPage = pageRange.start; idxPage < pageRange.end; idxPage++) { 802 | var pageLink = createPageLink(idxPage); 803 | 804 | pageNumbers.appendChild(pageLink); 805 | } 806 | 807 | if (pageRange.last) { 808 | var pageSeparator = document.createElement("div"); 809 | pageSeparator.setAttribute("class", "pagedtable-index-separator-right"); 810 | pageSeparator.appendChild(document.createTextNode("...")) 811 | pageNumbers.appendChild(pageSeparator); 812 | 813 | var pageLink = createPageLink(page.total - 1); 814 | pageNumbers.appendChild(pageLink); 815 | } 816 | 817 | if (data.length > page.rows) footer.appendChild(pageNumbers); 818 | 819 | var previous = document.createElement("a"); 820 | previous.appendChild(document.createTextNode("Previous")); 821 | previous.onclick = function() { 822 | page.setPageNumber(page.number - 1); 823 | renderBody(); 824 | renderFooter(); 825 | 826 | triggerOnChange(); 827 | }; 828 | if (data.length > page.rows) footer.appendChild(previous); 829 | 830 | var infoLabel = document.createElement("div"); 831 | infoLabel.setAttribute("class", "pagedtable-info"); 832 | infoLabel.setAttribute("title", getLabelInfo()); 833 | infoLabel.appendChild(document.createTextNode(getLabelInfo())); 834 | footer.appendChild(infoLabel); 835 | 836 | var enabledClass = "pagedtable-index-nav"; 837 | var disabledClass = "pagedtable-index-nav pagedtable-index-nav-disabled"; 838 | previous.setAttribute("class", page.number <= 0 ? disabledClass : enabledClass); 839 | next.setAttribute("class", (page.number + 1) * page.rows >= data.length ? disabledClass : enabledClass); 840 | }; 841 | 842 | var measuresCell = null; 843 | 844 | var renderMeasures = function() { 845 | var measuresTable = document.createElement("table"); 846 | measuresTable.style.visibility = "hidden"; 847 | measuresTable.style.position = "absolute"; 848 | measuresTable.style.whiteSpace = "nowrap"; 849 | measuresTable.style.height = "auto"; 850 | measuresTable.style.width = "auto"; 851 | 852 | var measuresRow = document.createElement("tr"); 853 | measuresTable.appendChild(measuresRow); 854 | 855 | measuresCell = document.createElement("td"); 856 | var sampleString = "ABCDEFGHIJ0123456789"; 857 | measuresCell.appendChild(document.createTextNode(sampleString)); 858 | 859 | measuresRow.appendChild(measuresCell); 860 | 861 | tableDiv.appendChild(measuresTable); 862 | } 863 | 864 | me.init = function() { 865 | tableDiv = document.createElement("div"); 866 | pagedTable.appendChild(tableDiv); 867 | var pagedTableClass = data.length > 0 ? 868 | "pagedtable pagedtable-not-empty" : 869 | "pagedtable pagedtable-empty"; 870 | 871 | if (columns.total == 0 || (columns.emptyNames() && data.length == 0)) { 872 | pagedTableClass = pagedTableClass + " pagedtable-empty-columns"; 873 | } 874 | 875 | tableDiv.setAttribute("class", pagedTableClass); 876 | 877 | renderMeasures(); 878 | measurer.calculate(measuresCell); 879 | columns.calculateWidths(measurer.measures); 880 | 881 | table = document.createElement("table"); 882 | table.setAttribute("cellspacing", "0"); 883 | table.setAttribute("class", "table table-condensed"); 884 | tableDiv.appendChild(table); 885 | 886 | table.appendChild(document.createElement("thead")); 887 | 888 | var footerDiv = document.createElement("div"); 889 | footerDiv.setAttribute("class", "pagedtable-footer"); 890 | tableDiv.appendChild(footerDiv); 891 | 892 | // if the host has not yet provided horizontal space, render hidden 893 | if (tableDiv.clientWidth <= 0) { 894 | tableDiv.style.opacity = "0"; 895 | } 896 | 897 | me.render(); 898 | 899 | // retry seizing columns later if the host has not provided space 900 | function retryFit() { 901 | if (tableDiv.clientWidth <= 0) { 902 | setTimeout(retryFit, 100); 903 | } else { 904 | me.render(); 905 | triggerOnChange(); 906 | } 907 | } 908 | if (tableDiv.clientWidth <= 0) { 909 | retryFit(); 910 | } 911 | }; 912 | 913 | var registerWidths = function() { 914 | columns.subset = columns.subset.map(function(column) { 915 | column.width = columns.widths[column.name].inner; 916 | return column; 917 | }); 918 | }; 919 | 920 | var parsePadding = function(value) { 921 | return parseInt(value) >= 0 ? parseInt(value) : 0; 922 | }; 923 | 924 | me.fixedHeight = function() { 925 | return options.rows.max != null; 926 | } 927 | 928 | me.fitRows = function() { 929 | if (me.fixedHeight()) 930 | return; 931 | 932 | measurer.calculate(measuresCell); 933 | 934 | var rows = options.rows.min !== null ? options.rows.min : 0; 935 | var headerHeight = header !== null && header.offsetHeight > 0 ? header.offsetHeight : 0; 936 | var footerHeight = footer !== null && footer.offsetHeight > 0 ? footer.offsetHeight : 0; 937 | 938 | if (pagedTable.offsetHeight > 0) { 939 | var availableHeight = pagedTable.offsetHeight - headerHeight - footerHeight; 940 | rows = Math.floor((availableHeight) / measurer.measures.height); 941 | } 942 | 943 | rows = options.rows.min !== null ? Math.max(options.rows.min, rows) : rows; 944 | 945 | page.setRows(rows); 946 | } 947 | 948 | // The goal of this function is to add as many columns as possible 949 | // starting from left-to-right, when the right most limit is reached 950 | // it tries to add columns from the left as well. 951 | // 952 | // When startBackwards is true columns are added from right-to-left 953 | me.fitColumns = function(startBackwards) { 954 | measurer.calculate(measuresCell); 955 | columns.calculateWidths(measurer.measures); 956 | 957 | if (tableDiv.clientWidth > 0) { 958 | tableDiv.style.opacity = 1; 959 | } 960 | 961 | var visibleColumns = tableDiv.clientWidth <= 0 ? Math.max(columns.min, 1) : 1; 962 | var columnNumber = columns.number; 963 | var paddingCount = 0; 964 | 965 | // track a list of added columns as we build the visible ones to allow us 966 | // to remove columns when they don't fit anymore. 967 | var columnHistory = []; 968 | 969 | var lastTableHeight = 0; 970 | var backwards = startBackwards; 971 | 972 | var tableDivStyle = window.getComputedStyle(tableDiv, null); 973 | var tableDivPadding = parsePadding(tableDivStyle.paddingLeft) + 974 | parsePadding(tableDivStyle.paddingRight); 975 | 976 | var addPaddingCol = false; 977 | var currentWidth = 0; 978 | 979 | while (true) { 980 | columns.setVisibleColumns(columnNumber, visibleColumns, paddingCount); 981 | currentWidth = columns.getWidth(); 982 | 983 | if (tableDiv.clientWidth - tableDivPadding < currentWidth) { 984 | break; 985 | } 986 | 987 | columnHistory.push({ 988 | columnNumber: columnNumber, 989 | visibleColumns: visibleColumns, 990 | paddingCount: paddingCount 991 | }); 992 | 993 | if (columnHistory.length > 100) { 994 | console.error("More than 100 tries to fit columns, aborting"); 995 | break; 996 | } 997 | 998 | if (columns.max !== null && 999 | columns.visible + columns.getPaddingCount() >= columns.max) { 1000 | break; 1001 | } 1002 | 1003 | // if we run out of right-columns 1004 | if (!backwards && columnNumber + columns.visible >= columns.total) { 1005 | // if we started adding right-columns, try adding left-columns 1006 | if (!startBackwards && columnNumber > 0) { 1007 | backwards = true; 1008 | } 1009 | else if (columns.min === null || visibleColumns + columns.getPaddingCount() >= columns.min) { 1010 | break; 1011 | } 1012 | else { 1013 | paddingCount = paddingCount + 1; 1014 | } 1015 | } 1016 | 1017 | // if we run out of left-columns 1018 | if (backwards && columnNumber == 0) { 1019 | // if we started adding left-columns, try adding right-columns 1020 | if (startBackwards && columnNumber + columns.visible < columns.total) { 1021 | backwards = false; 1022 | } 1023 | else if (columns.min === null || visibleColumns + columns.getPaddingCount() >= columns.min) { 1024 | break; 1025 | } 1026 | else { 1027 | paddingCount = paddingCount + 1; 1028 | } 1029 | } 1030 | 1031 | // when moving backwards try fitting left columns first 1032 | if (backwards && columnNumber > 0) { 1033 | columnNumber = columnNumber - 1; 1034 | } 1035 | 1036 | if (columnNumber + visibleColumns < columns.total) { 1037 | visibleColumns = visibleColumns + 1; 1038 | } 1039 | } 1040 | 1041 | var lastRenderableColumn = { 1042 | columnNumber: columnNumber, 1043 | visibleColumns: visibleColumns, 1044 | paddingCount: paddingCount 1045 | }; 1046 | 1047 | if (columnHistory.length > 0) { 1048 | lastRenderableColumn = columnHistory[columnHistory.length - 1]; 1049 | } 1050 | 1051 | columns.setVisibleColumns( 1052 | lastRenderableColumn.columnNumber, 1053 | lastRenderableColumn.visibleColumns, 1054 | lastRenderableColumn.paddingCount); 1055 | 1056 | if (pagedTable.offsetWidth > 0) { 1057 | page.setVisiblePages(Math.max(Math.ceil(1.0 * (pagedTable.offsetWidth - 250) / 40), 2)); 1058 | } 1059 | 1060 | registerWidths(); 1061 | }; 1062 | 1063 | me.fit = function(startBackwards) { 1064 | me.fitRows(); 1065 | me.fitColumns(startBackwards); 1066 | } 1067 | 1068 | me.render = function() { 1069 | me.fitColumns(false); 1070 | 1071 | // render header/footer to measure height accurately 1072 | renderHeader(); 1073 | renderFooter(); 1074 | 1075 | me.fitRows(); 1076 | renderBody(); 1077 | 1078 | // re-render footer to match new rows 1079 | renderFooter(); 1080 | } 1081 | 1082 | var resizeLastWidth = -1; 1083 | var resizeLastHeight = -1; 1084 | var resizeNewWidth = -1; 1085 | var resizeNewHeight = -1; 1086 | var resizePending = false; 1087 | 1088 | me.resize = function(newWidth, newHeight) { 1089 | 1090 | function resizeDelayed() { 1091 | resizePending = false; 1092 | 1093 | if ( 1094 | (resizeNewWidth !== resizeLastWidth) || 1095 | (!me.fixedHeight() && resizeNewHeight !== resizeLastHeight) 1096 | ) { 1097 | resizeLastWidth = resizeNewWidth; 1098 | resizeLastHeight = resizeNewHeight; 1099 | 1100 | setTimeout(resizeDelayed, 200); 1101 | resizePending = true; 1102 | } else { 1103 | me.render(); 1104 | triggerOnChange(); 1105 | 1106 | resizeLastWidth = -1; 1107 | resizeLastHeight = -1; 1108 | } 1109 | } 1110 | 1111 | resizeNewWidth = newWidth; 1112 | resizeNewHeight = newHeight; 1113 | 1114 | if (!resizePending) resizeDelayed(); 1115 | }; 1116 | }; 1117 | 1118 | var PagedTableDoc; 1119 | (function (PagedTableDoc) { 1120 | var allPagedTables = []; 1121 | 1122 | PagedTableDoc.initAll = function() { 1123 | allPagedTables = []; 1124 | 1125 | var pagedTables = [].slice.call(document.querySelectorAll('[data-pagedtable="false"],[data-pagedtable=""]')); 1126 | pagedTables.forEach(function(pagedTable, idx) { 1127 | pagedTable.setAttribute("data-pagedtable", "true"); 1128 | pagedTable.setAttribute("pagedtable-page", 0); 1129 | pagedTable.setAttribute("class", "pagedtable-wrapper"); 1130 | 1131 | var pagedTableInstance = new PagedTable(pagedTable); 1132 | pagedTableInstance.init(); 1133 | 1134 | allPagedTables.push(pagedTableInstance); 1135 | }); 1136 | }; 1137 | 1138 | PagedTableDoc.resizeAll = function() { 1139 | allPagedTables.forEach(function(pagedTable) { 1140 | pagedTable.render(); 1141 | }); 1142 | }; 1143 | 1144 | window.addEventListener("resize", PagedTableDoc.resizeAll); 1145 | 1146 | return PagedTableDoc; 1147 | })(PagedTableDoc || (PagedTableDoc = {})); 1148 | 1149 | window.onload = function() { 1150 | PagedTableDoc.initAll(); 1151 | }; 1152 | -------------------------------------------------------------------------------- /slides/libs/remark-css-0.0.1/default.css: -------------------------------------------------------------------------------- 1 | a, a > code { 2 | color: rgb(249, 38, 114); 3 | text-decoration: none; 4 | } 5 | .footnote { 6 | position: absolute; 7 | bottom: 3em; 8 | padding-right: 4em; 9 | font-size: 90%; 10 | } 11 | .remark-code-line-highlighted { background-color: #ffff88; } 12 | 13 | .inverse { 14 | background-color: #272822; 15 | color: #d6d6d6; 16 | text-shadow: 0 0 20px #333; 17 | } 18 | .inverse h1, .inverse h2, .inverse h3 { 19 | color: #f3f3f3; 20 | } 21 | /* Two-column layout */ 22 | .left-column { 23 | color: #777; 24 | width: 20%; 25 | height: 92%; 26 | float: left; 27 | } 28 | .left-column h2:last-of-type, .left-column h3:last-child { 29 | color: #000; 30 | } 31 | .right-column { 32 | width: 75%; 33 | float: right; 34 | padding-top: 1em; 35 | } 36 | .pull-left { 37 | float: left; 38 | width: 47%; 39 | } 40 | .pull-right { 41 | float: right; 42 | width: 47%; 43 | } 44 | .pull-right ~ * { 45 | clear: both; 46 | } 47 | img, video, iframe { 48 | max-width: 100%; 49 | } 50 | blockquote { 51 | border-left: solid 5px lightgray; 52 | padding-left: 1em; 53 | } 54 | .remark-slide table { 55 | margin: auto; 56 | border-top: 1px solid #666; 57 | border-bottom: 1px solid #666; 58 | } 59 | .remark-slide table thead th { border-bottom: 1px solid #ddd; } 60 | th, td { padding: 5px; } 61 | .remark-slide thead, .remark-slide tfoot, .remark-slide tr:nth-child(even) { background: #eee } 62 | 63 | @page { margin: 0; } 64 | @media print { 65 | .remark-slide-scaler { 66 | width: 100% !important; 67 | height: 100% !important; 68 | transform: scale(1) !important; 69 | top: 0 !important; 70 | left: 0 !important; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /slides/setup.Rmd: -------------------------------------------------------------------------------- 1 | ```{r setup, include=FALSE} 2 | knitr::opts_chunk$set(eval = F, 3 | warning = F, 4 | message = F, 5 | rows.print = 5) 6 | 7 | 8 | ``` 9 | 10 | layout: true 11 | 12 |
18 | 19 | --- -------------------------------------------------------------------------------- /slides/slides.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Getting Started with R" 3 | author: "R for the Rest of Us" 4 | output: 5 | xaringan::moon_reader: 6 | df_print: paged 7 | css: ["style.css", "default"] 8 | lib_dir: libs 9 | nature: 10 | highlightStyle: github 11 | highlightLines: true 12 | countIncrementalSlides: false 13 | ratio: 16:9 14 | --- 15 | 16 | ```{r child = "setup.Rmd"} 17 | ``` 18 | 19 | 20 | 21 | ```{r packages, include = F, eval = T} 22 | 23 | 24 | library(tidyverse) 25 | library(skimr) 26 | library(janitor) 27 | library(DT) 28 | library(here) 29 | library(kableExtra) 30 | library(knitr) 31 | 32 | 33 | ``` 34 | 35 | class: center, middle, dk-section-title 36 | 37 | background-image: url("images/installation.jpeg") 38 | 39 | # Installation 40 | 41 | 42 | 43 | --- 44 | 45 | ## Install R 46 | 47 | The first thing you need to do is download the R software. Go to the [Comprehensive R Archive Network (aka “CRAN”) website](https://cran.r-project.org/) and download the software for your operating system (Windows, Mac, or Linux). 48 | 49 |  50 | 51 | 52 | --- 53 | 54 | 55 | ### Working Directly in R 56 | 57 |  58 | 59 | 60 | --- 61 | 62 | ### Working Directly in R 63 | 64 | 1. Enter: 2 + 2 65 | 66 | 2. Hit return 67 | 68 | 3. View result 69 | 70 | --- 71 | 72 | class:inverse 73 | 74 | ### Your Turn 75 | 76 | 1. Download and Install R 77 | 78 | -- 79 | 80 | 1. Open R 81 | 82 | -- 83 | 84 | 1. Use any mathematical operators (+, -, /, and *) to create an expression and make sure it works as expected 85 | 86 | 87 | --- 88 | 89 | 90 | ## RStudio 91 | 92 | -- 93 | 94 | .center[ 95 |  96 | 97 | .small[Courtesy [Modern Dive](http://moderndive.com/2-getting-started.html#what-are-r-and-rstudio)] 98 | ] 99 | 100 | --- 101 | 102 | ### RStudio 103 | 104 | If you use RStudio, you’ll have a graphical user interface, the ability to see all of your stored information, and much more. 105 | 106 |  107 | 108 | 109 | --- 110 | 111 | ### Download RStudio 112 | 113 | Download RStudio at the [RStudio website](https://www.rstudio.com/products/rstudio/download/#download). Ignore the various versions listed there. All you need is the latest version of RStudio Desktop. 114 | 115 |  116 | 117 | 118 | --- 119 | 120 | 121 | ### Tour of RStudio 122 | 123 | .center[ 124 |  125 | ] 126 | 127 | 128 | 129 | --- 130 | 131 | class:inverse 132 | 133 | ### Your Turn 134 | 135 | 1. Download and Install RStudio 136 | 137 | -- 138 | 139 | 1. Open RStudio 140 | 141 | -- 142 | 143 | 1. Working in the console pane, use any mathematical operators (+, -, /, and *) to create an expression and make sure it works as expected 144 | 145 | --- 146 | 147 | class: center, middle, dk-section-title 148 | 149 | background-image: url("images/projects.jpeg") 150 | 151 | # Projects 152 | 153 | --- 154 | 155 | ## Projects 156 | 157 | -- 158 | 159 | Projects allow you to keep a collection of files all together, including: 160 | 161 | -- 162 | 163 | - R scripts 164 | 165 | -- 166 | 167 | - RMarkdown files (more on those soon) 168 | 169 | -- 170 | 171 | - Data files 172 | 173 | -- 174 | 175 | - And much more! 176 | 177 | 178 | --- 179 | 180 | ### Sample Project 181 | 182 | .center[ 183 |  184 | ] 185 | 186 | --- 187 | 188 | 189 | ### How to Create a Project 190 | 191 | 192 | 1. File -> New Project 193 | 194 | -- 195 | 196 | 2. Quit RStudio, Double-click .Rproj file to reopen project 197 | 198 | --- 199 | 200 | class:inverse 201 | 202 | ### Your Turn 203 | 204 | 1. Create a new project (doesn't matter if it's in a new or existing directory) 205 | 206 | -- 207 | 208 | 2. Quit RStudio, double-click the .Rproj file and reopen your project 209 | 210 | --- 211 | 212 | 213 | class: center, middle, dk-section-title 214 | 215 | background-image: url("images/download-course-project.jpeg") 216 | 217 | # Download Course Project 218 | 219 | --- 220 | 221 | class: inverse 222 | 223 | ## Your Turn 224 | 225 | -- 226 | 227 | Enter the following into the RStudio console pane: 228 | 229 | ```{r eval = F} 230 | install.packages("usethis") 231 | library(usethis) 232 | use_course("http://bit.ly/getting-started-with-r") 233 | ``` 234 | 235 | ??? 236 | 237 | You'll now have a copy of the project created for this course that we'll use from here on out 238 | 239 | --- 240 | 241 | 242 | class: center, middle, dk-section-title 243 | 244 | background-image: url("images/files.jpg") 245 | opacity: 0.5 246 | 247 | # Files in R 248 | 249 | --- 250 | 251 | 252 | ## File Types 253 | 254 | There are **two main file types** that you'll work with: 255 | 256 | .pull-left[ 257 | **R scripts (.R)** 258 | 259 | Text is assumed to be executable R code unless you comment it (more on this soon) 260 | 261 | ```{r} 262 | 263 | # This is a comment 264 | 265 | data <- read_csv("data.csv") 266 | 267 | ``` 268 | ] 269 | 270 | -- 271 | 272 | .pull-right[ 273 | 274 | **RMarkdown files (.Rmd)** 275 | 276 | Text is assumed to be text unless you put it in a code chunk (more on this soon) 277 | 278 |  279 | 280 | 281 | 282 | ] 283 | 284 | 285 | --- 286 | 287 | ## R Scripts 288 | 289 | 290 | Create new script file: File -> New File -> R Script 291 | 292 |  293 | 294 | --- 295 | 296 | 297 | ## How to Run Code 298 | 299 | Run the code: control + enter on Windows, command + enter on Mac keystrokes or use Run button 300 | 301 |  302 | 303 | ??? 304 | 305 | Note that you don't have to highlight code. 306 | 307 | You can just hit run anywhere on line to run code. 308 | 309 | --- 310 | 311 | ## Comments 312 | 313 | Do them for others, and for your future self. 314 | 315 | ```{r eval = F} 316 | 317 | # This is a comment 318 | 319 | head(data, n = 5) 320 | 321 | ``` 322 | 323 | --- 324 | class: center, middle, dk-section-title 325 | 326 | background-image: url("images/packages.jpg") 327 | 328 | # Packages 329 | 330 | --- 331 | 332 | ## Packages 333 | 334 | Packages add functionality that is not present in base R. 335 | 336 | They're where much of the power of R is found. 337 | 338 | -- 339 | 340 | .center[ 341 |  342 | 343 | .small[Courtesy [Modern Dive](http://moderndive.com/2-getting-started.html#packages)] 344 | ] 345 | 346 | 347 | --- 348 | 349 | ## Packages We'll Use 350 | 351 | .pull-left[ 352 | 353 | .center[ 354 |  355 | ] 356 | 357 | ] 358 | 359 | 360 | .pull-right[ 361 | 362 | ### `tidyverse` 363 | 364 | The [`tidyverse`](https://tidyverse.org/) is a collection of packages. 365 | 366 | We'll use [`readr`](https://readr.tidyverse.org/) to import data. 367 | 368 | ] 369 | 370 | --- 371 | 372 | ## Packages We'll Use 373 | 374 | 375 | 376 | .pull-left[ 377 | 378 | ### `skimr` 379 | 380 | [`skimr`](https://github.com/ropensci/skimr) provides easy summary statistics. 381 | 382 | ] 383 | 384 | 385 | .pull-right[ 386 | 387 | .center[ 388 |  389 | ] 390 | 391 | 392 | 393 | 394 | 395 | 396 | ] 397 | 398 | --- 399 | 400 | 401 | 402 | ## Install Packages 403 | 404 | The syntax to install packages is as follows. 405 | 406 | ```{r eval=F} 407 | install.packages("tidyverse") 408 | install.packages("skimr") 409 | ``` 410 | 411 | The package name must be in quotes. 412 | 413 | -- 414 | 415 | .dk-highlight-box[ 416 | Packages should be installed **once per computer** (i.e. once you've installed a package, you don't need to do it again on the same computer). 417 | ] 418 | 419 | --- 420 | 421 | ## Load Packages 422 | 423 | To load packages, use the following syntax: 424 | 425 | ```{r eval = T} 426 | library(tidyverse) 427 | library(skimr) 428 | ``` 429 | 430 | Package names don't need to be quoted here (though they can be). 431 | 432 | -- 433 | 434 | .dk-highlight-box[ 435 | Packages should be loaded **once per session** (i.e. every time you start working in R, you need to load any packages you want to use). 436 | ] 437 | 438 | 439 | 440 | --- 441 | 442 | 443 | 444 | class:inverse 445 | 446 | ## Your Turn 447 | 448 | 1. Open the project you downloaded before (it should be on your desktop) 449 | 450 | -- 451 | 452 | 1. Open the exercises.R file 453 | 454 | -- 455 | 456 | 1. Install the tidyverse and skimr packages using the install.packages function 457 | 458 | -- 459 | 460 | 1. Load the tidyverse and skimr packages using the library function 461 | 462 | --- 463 | 464 | class: center, middle, dk-section-title 465 | 466 | background-image: url("images/data.jpg") 467 | 468 | 469 | # Import Data 470 | 471 | 472 | 473 | --- 474 | 475 | ## Import Data 476 | 477 | Let's read data from a CSV file. 478 | 479 | 480 | ```{r eval = T, echo = F} 481 | 482 | faketucky <- read_csv(here("data", "faketucky.csv")) 483 | 484 | 485 | ``` 486 | 487 | ```{r} 488 | 489 | faketucky <- read_csv("data/faketucky.csv") 490 | 491 | 492 | ``` 493 | 494 | We now have a data frame/tibble called `faketucky` that we can work with in R. 495 | 496 | 497 | 498 | ??? 499 | 500 | - Tibbles are ["modern data frames"](https://cran.r-project.org/web/packages/tibble/vignettes/tibble.html). The main difference for our purposes is that tibbles print much more nicely within R. 501 | 502 | - We'll use the terms tibble and data frame interchangeably. 503 | 504 | - For Excel files, try `read_excel` from the `readxl` package. 505 | 506 | - For SPSS files, try `read_sav` from the `haven` package. 507 | 508 | 509 | --- 510 | 511 | 512 | ## R is Case Sensitive 513 | 514 | R is **case sensitive** so choose one of the following for all objects and **be consistent**. 515 | .pull-left[ 516 | **Option** 517 | 518 | snake_case 519 | 520 | camelCase 521 | 522 | periods.in.names 523 | ] 524 | 525 | -- 526 | 527 | .pull-right[ 528 | 529 | **Example** 530 | 531 | student_data 532 | 533 | studentData 534 | 535 | student.data 536 | ] 537 | 538 | 539 | 540 | 541 | --- 542 | 543 | 544 | ## Directories 545 | 546 | If the data file is in the working directory, you only need to specify its name. 547 | 548 | ```{r} 549 | faketucky <- read_csv("faketucky.csv") 550 | ``` 551 | 552 | -- 553 | 554 | If the data file is not in the working directory, you need to specify full path name. 555 | 556 | -- 557 | 558 | When specifying the path name use of forward slash (“/”) not backslash (“\”). 559 | 560 | ```{r} 561 | faketucky <- read_csv("data/faketucky.csv") 562 | ``` 563 | 564 | --- 565 | 566 | ## Where Does our Data Live? 567 | 568 | Data we have imported is available in the environment/history pane. 569 | 570 | .center[ 571 |  572 | ] 573 | 574 | --- 575 | class:inverse 576 | 577 | ## Your Turn 578 | 579 | 1. Open the exercises.R file 580 | 581 | -- 582 | 583 | 1. Import the faketucky data into a data frame called `faketucky`. 584 | 585 | -- 586 | 587 | 1. Make sure you see `faketucky` in your environment/history pane. 588 | 589 | --- 590 | class: center, middle, dk-section-title 591 | 592 | background-image: url("images/function.jpg") 593 | 594 | 595 | # Objects and Functions 596 | 597 | --- 598 | 599 | ## Objects and Functions 600 | 601 | -- 602 | 603 | > To understand computations in R, two slogans are helpful: 604 | 605 | -- 606 | 607 | > Everything that exists is an **object**, and 608 | 609 | -- 610 | 611 | > Everything that happens is a **function** call. 612 | 613 | -- 614 | 615 | John Chambers, quoted in [Hadley Wickham's Advanced R](http://adv-r.had.co.nz/Functions.html). 616 | 617 | 618 | --- 619 | 620 | ## Objects and Functions 621 | 622 | .center[] 623 | 624 | 625 | 626 | 627 | --- 628 | 629 | ## Assignment Operator 630 | 631 | .center[ 632 |  633 | ] 634 | 635 | -- 636 | 637 | We assign the result of the `read_csv` **function** to the `faketucky` **object** 638 | --- 639 | class: center, middle, dk-section-title 640 | 641 | background-image: url("images/glasses.jpeg") 642 | 643 | 644 | # Examine Our Data 645 | 646 | 647 | --- 648 | 649 | ## Examine Our Data 650 | 651 | There are many ways to look at our data. We'll talk about a few. 652 | 653 | 654 | --- 655 | 656 | ## `faketucky` 657 | 658 | If you type the name of your data frame (i.e. `faketucky`), R will output the following: 659 | ```{r} 660 | faketucky 661 | ``` 662 | 663 | -- 664 | 665 | ```{r eval = T, paged.print = F, echo = F} 666 | faketucky 667 | ``` 668 | 669 | --- 670 | 671 | ## `head` 672 | 673 | `head` shows us the first X rows. 674 | ```{r} 675 | head(faketucky, 5) 676 | ``` 677 | 678 | -- 679 | 680 | ```{r eval = T, paged.print = F, echo = F} 681 | head(faketucky, 5) 682 | ``` 683 | 684 | --- 685 | 686 | ## `head` 687 | 688 | ```{r} 689 | head(faketucky, 5) 690 | ``` 691 | 692 | -- 693 | 694 | .dk-highlight-box[ 695 | `faketucky` and the number 5 here are **arguments**. 696 | ] 697 | 698 | --- 699 | 700 | ## `tail` 701 | 702 | `tail` shows us the last X rows. 703 | ```{r} 704 | tail(faketucky, 5) 705 | ``` 706 | 707 | -- 708 | 709 | ```{r eval = T, paged.print = F, echo = F} 710 | tail(faketucky, 5) 711 | ``` 712 | 713 | --- 714 | 715 | ## `View` 716 | 717 | `View` (note capital V) opens the RStudio viewer (or click on a data frame in the environment pane). 718 | 719 | ```{r paged.print = F} 720 | View(faketucky) 721 | ``` 722 | 723 | --- 724 | 725 | 726 | 727 | ## `skimr` 728 | 729 | The skimr package provides more detailed information about our data frame. It is also broken up by the type of variable. 730 | 731 | ```{r} 732 | 733 | skim(faketucky) 734 | 735 | ``` 736 | 737 | -- 738 | 739 | ```{r eval = T, paged.print = F, echo = F} 740 | 741 | skim(faketucky) 742 | 743 | ``` 744 | 745 | --- 746 | 747 | class:inverse 748 | 749 | ## Your Turn 750 | 751 | 1. Open the file exercises.R 752 | 753 | -- 754 | 755 | 1. Follow the instructions to use the `head()`, `tail()`, `View()`, and `skim()` functions to examine your data. 756 | 757 | --- 758 | 759 | class: center, middle, dk-section-title 760 | 761 | background-image: url("images/issues.jpeg") 762 | 763 | # We've Got Issues! 764 | 765 | --- 766 | 767 | ## We've Got Issues! 768 | 769 | Several variables have max values of 999. This seems suspicious! 770 | 771 |  772 | 773 | 774 | --- 775 | 776 | ## We've Got Issues! 777 | 778 | Several variables show up as numeric, but we know they're **not actually numeric**. 779 | 780 | 781 |  782 | 783 | --- 784 | 785 | ## Let's Import Our Data Again 786 | 787 | We need to do two things: 788 | 789 | 790 | 791 | -- 792 | 793 | 1. Tell `read_csv` how to handle **missing data** 794 | 795 | -- 796 | 797 | 1. Make sure `read_csv` assigns the correct **data type** to each variable 798 | 799 | 800 | 801 | 802 | 803 | --- 804 | 805 | 806 | ## Missing Data 807 | 808 | Here's how we imported our data the first time: 809 | 810 | ```{r} 811 | faketucky <- read_csv("data/faketucky.csv") 812 | ``` 813 | 814 | -- 815 | 816 | To tell R which data is missing, simply add an argument to the `read_csv` function as follows: 817 | 818 | ```{r} 819 | faketucky <- read_csv("data/faketucky.csv", 820 | na = "999") #<< 821 | ``` 822 | 823 | ```{r eval = T, echo = F} 824 | faketucky <- read_csv(here("data", "faketucky.csv"), 825 | na = "999") 826 | 827 | ``` 828 | 829 | 830 | --- 831 | 832 | ## Missing Data 833 | 834 | If we skim our data again, we'll see that there are no longer 999 values. 835 | 836 | ```{r} 837 | skim(faketucky) 838 | 839 | ``` 840 | 841 | ??? 842 | 843 | Do this in R 844 | 845 | 846 | 847 | 848 | 849 | --- 850 | 851 | ## Data Types 852 | 853 | When you run `read_csv` you'll see the following message, which tells you the data types that have been assigned to your data frame. 854 | 855 | -- 856 | 857 | 858 | ```{r} 859 | Parsed with column specification: 860 | cols( 861 | student_id = col_double(), 862 | first_high_school_attended = col_character(), 863 | school_district = col_character(), 864 | male = col_double(), 865 | race_ethnicity = col_character(), 866 | free_and_reduced_lunch = col_double(), 867 | percent_absent = col_double(), 868 | gpa = col_double(), 869 | act_reading_score = col_double(), 870 | act_math_score = col_double(), 871 | received_high_school_diploma = col_double(), 872 | enrolled_in_college = col_double() 873 | ) 874 | ``` 875 | 876 | --- 877 | 878 | ## Data Types 879 | 880 | 881 | - **Double/Numeric** (e.g. 2.5) 882 | 883 | -- 884 | 885 | - **Character** (e.g. "Male") 886 | 887 | .small[There are [many other data types in R](https://www.statmethods.net/input/datatypes.html) that we won't discuss in this course. 888 | ] 889 | 890 | --- 891 | 892 | ## Data Types 893 | 894 | ```{r eval = T, echo = F} 895 | 896 | faketucky <- read_csv(here("data/faketucky.csv"), 897 | na = "999", 898 | col_types = list(enrolled_in_college = col_character(), 899 | free_and_reduced_lunch = col_character(), 900 | male = col_character(), 901 | received_high_school_diploma = col_character())) 902 | 903 | 904 | ``` 905 | 906 | ```{r} 907 | 908 | faketucky <- read_csv("data/faketucky.csv", 909 | na = "999", 910 | col_types = list(enrolled_in_college = col_character(), #<< 911 | free_and_reduced_lunch = col_character(), #<< 912 | male = col_character(), #<< 913 | received_high_school_diploma = col_character())) #<< 914 | 915 | 916 | ``` 917 | 918 | 919 | 920 | 921 | --- 922 | 923 | 924 | 925 | class:inverse 926 | 927 | ## Your Turn 928 | 929 | 1. Open the file exercises.R and change the code so that you correctly import the `faketucky` data frame, telling `read_csv` which data is missing and explictly defining column types where necessary. 930 | 931 | -- 932 | 933 | 1. After you make changes to how you import your data, rerun the code in the Examine Data section to make sure everything worked! 934 | 935 | --- 936 | 937 | 938 | class: center, middle, dk-section-title 939 | 940 | background-image: url("images/help.jpeg") 941 | 942 | # Getting Help 943 | 944 | --- 945 | 946 | ### ?function 947 | 948 | Use the ? to get help about anything you're confused about 949 | 950 | ```{r} 951 | 952 | ?read_csv 953 | 954 | ``` 955 | 956 | --- 957 | 958 | ## Tidyverse Website 959 | 960 | [](https://www.tidyverse.org/) 961 | 962 | --- 963 | 964 | 965 | ## Package Vignettes 966 | 967 | [](https://cran.r-project.org/web/packages/skimr/vignettes/Using_skimr.html) 968 | 969 | --- 970 | 971 | ## Twitter 972 | 973 | [](https://twitter.com/search?q=%23rstats) 974 | 975 | --- 976 | 977 | ## R for Data Science Community 978 | 979 | [](https://www.rfordatasci.com/) 980 | 981 | --- 982 | 983 | ## Google 984 | 985 | [](https://twitter.com/ekaleedmiston/status/1081221822186696706) 986 | 987 | 988 | -------------------------------------------------------------------------------- /slides/slides.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |