Learn basics of R workshop KPRA

Zahid Asghar

2026-09-12

Outline

  • Introduction to R and RStudio
  • Reproducible data analysis with R Markdown
  • Loading data
  • Data visualization
  • Data wrangling
  • Basic R syntax
  • What next?
  • Hands on exercises

Materials

  • All source code are taken from https://github.com/mine-cetinkaya-rundel/rworkshop-mem

Introduction to R and RStudio

What is R and RStudio

  • R: Statistical programming language

  • RStudio:

    • Integtrated development environment for R
    • Powerful and productive user interface for R
  • Both are free and open-source

Getting started

  • Traditionally you would install R and RStudio on your computer

  • Local installation instructions will be provided at the end of the workshop

Anatomy of RStudio

  • Left: Console
    • Text on top at launch: version of R that you’re running
    • Below that is the prompt
  • Upper right: Workspace and command history
  • Lower right: Plots, access to files, help, packages, data viewer

R Splash Screen

What version am I using?

  • The version of R is text that pops up in the Console when you start RStudio

  • To find out the version of RStudio go to Help \(\rightarrow\) About RStudio

  • It’s good practice to keep both R and RStudio up to date

R packages

  • Packages are the fundamental units of reproducible R code. They include reusable R functions, the documentation that describes how to use them, and (often) sample data. From

  • We will use the ggplot2 package for plots and dplyr for data wrangling in this workshop

  • Install these packages by running the following in the Console:

  • Then, load the packages by running the following:
  • This is just one way of installing a package, there is also a GUI approach in the Packages pane in RStudio

Reproducible data analysis with Quarto

What is Quarto?

  • Quarto is an authoring format that enables easy creation of dynamic documents, presentations, and reports from R/Python/Julia.

  • It combines the core syntax of markdown (an easy-to-write plain text format) with embedded R code chunks that are run so their output can be included in the final document.

  • Quarto documents are fully reproducible (they can be automatically regenerated whenever underlying R/Python/Julia code or data changes).

Source

Your turn!

Create your first Quarto document, knit it, and examine the source code and the output.

  1. File \(\rightarrow\) Quarto Document…

  2. Enter a title (e.g. “My first Quarto document”) and author info

  3. Choose Document as file type, and HTML as the output

  4. Hit OK

  5. Click Knit HTML in the new document, which will prompt you to save your document

    • Naming tip: Do not use spaces
    • Viewing tip: Click on the down arrow next to Knit HTML and select View in Pane

Quarto basics

R Code Chunks

Within an R Markdown file, R Code Chunks can be embedded using the native Markdown syntax for fenced code regions.

Code chunks

Your turn!

How many code chunks are in your R Markdown document?

What does each code chunk do? You may not understand the R syntax yet, but you should be able to compare the source file and the output to answer this question.

Inline R Code

You can also evaluate R expressions inline by enclosing the expression within a single back-tick qualified with r. For example, the following code: I counted 2 trucks on highway.

Results in this output: “I counted 2 red trucks on the highway.”

Your turn!

Suppose Sammy works on average 8.37 hours per day, 5 days per week. How many hours does Sammy work on average per week?

Add a sentence to your document that includes simple inline R code that answers this question, along the lines of…

“Sammy works 8.37 * 5 hours per week, on average.”

Workspaces

R Markdown workspace and Console workspace are independent of each other

  • If you define a variable in your Console and it shows up in the Environment tab, it is not going to be automatically included in your R Markdown document

  • If you define a variable in your R Markdown document, it won’t automatically be available in your Console

[ Demo ]

Tip: Use the Run all previous chunks in the source file and Run current chunk code functionality in the buttons in each code chunk to help manage workspaces.

Workspaces and reproducibilty

  • The fact that the two workspaces do not automatically have access to the same variables might / will be frustrating at first.

  • But this is not a bug, in fact, it’s a functionality that helps reproducibility, as it ensures that all variables, functions, etc. that are being used in the R Markdown document are explicitly defined or loaded.

Your turn!

  1. Define x = 2 in the Console. Then, in your Console run x * 3. Does your code run as expected?

  2. Now, insert a new code chunk in your R Markdown document and in this chunk type x * 3 only. Knit your document. Does the document compile, or do you get an error? If you get an error, what does the error say, and how can you fix it? Implement the fix and Knit your document. Make sure you are able to compile without errors before you move on.

Tip: Insert a new code chunk bu clicking Chunks \(\rightarrow\) Insert Chunk.

  1. Next insert another code chunk in your R Markdown document and define y = 4 and calculate y + 5. Knit your document. Does everything work as expected?

  2. Now run y + 5 in your Console. Does your code run as expected or do you get an error? If you get an error, what does the error say, and how can you fix it? Implement the fix.

Code chunk options

  • You can hide the code, hide the result, hide warnings, messages, etc.

  • Refer to the handy R Markdown cheatsheet

  • Another good reference: http://rmarkdown.rstudio.com/authoring_rcodechunks.html

Loading data

NC DOT Fatal Crashes in North Carolina

View the names of variables via

##  [1] "geo_point"      "geo_shape"      "bike_race"      "city"          
##  [5] "bike_pos"       "num_units"      "crash_hour"     "locality"      
##  [9] "bike_sex"       "drvr_veh_typ"   "num_bikes_no"   "bike_alc_drg"  
## [13] "num_bikes_bi"   "rte_invd_cd"    "drvr_race"      "workzone"      
## [17] "num_bikes_ci"   "bike_age_group" "crash_type"     "rd_defects"    
## [21] "crash_alcoh"    "bike_alcoho"    "rd_conditio"    "dstnc_mi_frm"  
## [25] "rural_urban"    "hit_run"        "crash_date"     "num_bikes_ui"  
## [29] "crash_time"     "drvr_sex"       "drvr_alcoho"    "developmen"    
## [33] "crash_sevr"     "ambulance_req"  "drvr_injury"    "object_id"     
## [37] "crash_month"    "num_bikes_ki"   "rd_characte"    "region"        
## [41] "bike_dir"       "traff_cntrl"    "crash_day"      "crash_location"
## [45] "bike_age"       "num_bikes_to"   "rd_config"      "num_lanes"     
## [49] "num_bikes_ai"   "drvr_alc_drg"   "on_road"        "rd_surface"    
## [53] "towrd_rd"       "rd_feature"     "crash_grp"      "rd_class"      
## [57] "bike_injury"    "county"         "drvr_age"       "weather"       
## [61] "frm_rd"         "drvr_est_spd"   "speed_limit"    "crash_year"    
## [65] "light_cond"     "drvr_age_group"

and see detailed descriptions at https://stat.duke.edu/~mc301/data/nc_bike_crash.html.

Aside: Strings (characters) vs factors

  • By default R will convert character vectors into factors when they are included in a data frame.

  • Sometimes this is useful, sometimes it isn’t – either way it is important to know what type/class you are working with.

  • This behavior can be changed using the stringsAsFactors = FALSE when loading a data drame.

Viewing your data

  • In the Environment, click on the name of the data frame to view it in the data viewer

  • Use the str() function to compactly display the internal structure of an R object

## tibble [7,467 × 66] (S3: tbl_df/tbl/data.frame)
##  $ geo_point     : chr [1:7467] "35.3336070056, -77.9955023901" "36.3151872016, -78.4057025669" "35.5246969313, -81.2295033733" "34.3314967628, -78.7080025567" ...
##  $ geo_shape     : chr [1:7467] "{\"type\": \"Point\", \"coordinates\": [-77.99550239012649, 35.33360700564749]}" "{\"type\": \"Point\", \"coordinates\": [-78.4057025668518, 36.31518720156319]}" "{\"type\": \"Point\", \"coordinates\": [-81.22950337331442, 35.524696931320605]}" "{\"type\": \"Point\", \"coordinates\": [-78.70800255666208, 34.33149676278382]}" ...
##  $ bike_race     : chr [1:7467] "Black" "Black" "White" "Black" ...
##  $ city          : chr [1:7467] "None - Rural Crash" "Henderson" "None - Rural Crash" "Whiteville" ...
##  $ bike_pos      : chr [1:7467] "Bike Lane / Paved Shoulder" "Travel Lane" "Travel Lane" "Unknown" ...
##  $ num_units     : num [1:7467] 2 2 2 2 2 2 2 2 2 2 ...
##  $ crash_hour    : num [1:7467] 6 20 18 18 13 17 17 7 15 2 ...
##  $ locality      : chr [1:7467] "Rural (<30% Developed)" "Mixed (30% To 70% Developed)" "Rural (<30% Developed)" "Urban (>70% Developed)" ...
##  $ bike_sex      : chr [1:7467] "Male" "Male" "Male" "Male" ...
##  $ drvr_veh_typ  : chr [1:7467] "Single Unit Truck (2-Axle, 6-Tire)" "Unknown" "Passenger Car" "Passenger Car" ...
##  $ num_bikes_no  : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ bike_alc_drg  : chr [1:7467] NA NA NA NA ...
##  $ num_bikes_bi  : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ rte_invd_cd   : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ drvr_race     : chr [1:7467] "White" "Unknown/Missing" "Hispanic" "Black" ...
##  $ workzone      : chr [1:7467] "No" "No" "No" "No" ...
##  $ num_bikes_ci  : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ bike_age_group: chr [1:7467] "50-59" "60-69" "30-39" "50-59" ...
##  $ crash_type    : chr [1:7467] "Motorist Overtaking - Undetected Bicyclist" "Bicyclist Ride Out - Sign-Controlled Intersection" "Motorist Overtaking - Undetected Bicyclist" "Bicyclist Ride Out - Signalized  Intersection" ...
##  $ rd_defects    : chr [1:7467] "None" "Unknown" "None" "None" ...
##  $ crash_alcoh   : chr [1:7467] "No" "No" "No" "Yes" ...
##  $ bike_alcoho   : chr [1:7467] "No" "No" "No" "Yes" ...
##  $ rd_conditio   : chr [1:7467] "Dry" "Dry" "Dry" "Water (Standing, Moving)" ...
##  $ dstnc_mi_frm  : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ rural_urban   : chr [1:7467] "Rural" "Urban" "Rural" "Urban" ...
##  $ hit_run       : chr [1:7467] "No" "Yes" "No" "No" ...
##  $ crash_date    : chr [1:7467] "11DEC2013" "20NOV2013" "03NOV2013" "14DEC2013" ...
##  $ num_bikes_ui  : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ crash_time    : 'hms' num [1:7467] 06:10:00 20:41:00 18:05:00 18:34:00 ...
##   ..- attr(*, "units")= chr "secs"
##  $ drvr_sex      : chr [1:7467] "Male" "Unknown" "Female" "Male" ...
##  $ drvr_alcoho   : chr [1:7467] "No" "Missing" "No" "No" ...
##  $ developmen    : chr [1:7467] "Farms, Woods, Pastures" "Residential" "Farms, Woods, Pastures" "Commercial" ...
##  $ crash_sevr    : chr [1:7467] "B: Evident Injury" "C: Possible Injury" "C: Possible Injury" "C: Possible Injury" ...
##  $ ambulance_req : chr [1:7467] "Yes" "No" "Yes" "Yes" ...
##  $ drvr_injury   : chr [1:7467] "O: No Injury" "Unknown Injury" "O: No Injury" "O: No Injury" ...
##  $ object_id     : num [1:7467] 1686 1674 1673 1687 1653 ...
##  $ crash_month   : chr [1:7467] "December" "November" "November" "December" ...
##  $ num_bikes_ki  : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ rd_characte   : chr [1:7467] "Straight - Level" "Straight - Level" "Straight - Grade" "Straight - Level" ...
##  $ region        : chr [1:7467] "Coastal" "Piedmont" "Piedmont" "Coastal" ...
##  $ bike_dir      : chr [1:7467] "With Traffic" "With Traffic" "With Traffic" "Unknown" ...
##  $ traff_cntrl   : chr [1:7467] "No Control Present" "Stop Sign" "Double Yellow Line, No Passing Zone" "No Control Present" ...
##  $ crash_day     : chr [1:7467] "Wednesday" "Wednesday" "Sunday" "Saturday" ...
##  $ crash_location: chr [1:7467] "Non-Intersection" "Intersection" "Non-Intersection" "Intersection" ...
##  $ bike_age      : num [1:7467] 52 66 33 52 22 15 41 14 16 54 ...
##   ..- attr(*, "problems")= tibble [113 × 4] (S3: tbl_df/tbl/data.frame)
##   .. ..$ row     : int [1:113] 110 159 184 209 271 274 305 382 452 461 ...
##   .. ..$ col     : int [1:113] NA NA NA NA NA NA NA NA NA NA ...
##   .. ..$ expected: chr [1:113] "a number" "a number" "a number" "a number" ...
##   .. ..$ actual  : chr [1:113] "Unknown" "Unknown" "Unknown" "Unknown" ...
##  $ num_bikes_to  : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ rd_config     : chr [1:7467] "Two-Way, Not Divided" "Two-Way, Divided, Unprotected Median" "Two-Way, Not Divided" "Two-Way, Not Divided" ...
##  $ num_lanes     : chr [1:7467] "2 lanes" "2 lanes" "2 lanes" "1 lane" ...
##  $ num_bikes_ai  : num [1:7467] 0 0 0 0 0 0 0 0 0 0 ...
##  $ drvr_alc_drg  : chr [1:7467] NA NA NA NA ...
##  $ on_road       : chr [1:7467] "SR 1915" "NICHOLAS ST" "US 321" "W BURKHEAD ST" ...
##  $ rd_surface    : chr [1:7467] "Coarse Asphalt" "Smooth Asphalt" "Smooth Asphalt" "Coarse Asphalt" ...
##  $ towrd_rd      : chr [1:7467] NA NA NA NA ...
##  $ rd_feature    : chr [1:7467] "No Special Feature" "T-Intersection" "No Special Feature" "No Special Feature" ...
##  $ crash_grp     : chr [1:7467] "Motorist Overtaking Bicyclist" "Bicyclist Failed to Yield - Sign-Controlled Intersection" "Motorist Overtaking Bicyclist" "Bicyclist Failed to Yield - Signalized Intersection" ...
##  $ rd_class      : chr [1:7467] "State Secondary Route" "Local Street" "US Route" "Local Street" ...
##  $ bike_injury   : chr [1:7467] "B: Evident Injury" "C: Possible Injury" "C: Possible Injury" "C: Possible Injury" ...
##  $ county        : chr [1:7467] "Wayne" "Vance" "Lincoln" "Columbus" ...
##  $ drvr_age      : chr [1:7467] "34" "Unknown" "37" "55" ...
##  $ weather       : chr [1:7467] "Clear" "Clear" "Clear" "Rain" ...
##  $ frm_rd        : chr [1:7467] NA NA NA NA ...
##  $ drvr_est_spd  : chr [1:7467] "51-55 mph" "6-10 mph" "41-45 mph" "11-15 mph" ...
##  $ speed_limit   : chr [1:7467] "50 - 55  MPH" "30 - 35  MPH" "50 - 55  MPH" "30 - 35  MPH" ...
##  $ crash_year    : num [1:7467] 2013 2013 2013 2013 2013 ...
##  $ light_cond    : chr [1:7467] "Dark - Roadway Not Lighted" "Unknown" "Dark - Roadway Not Lighted" "Dark - Lighted Roadway" ...
##  $ drvr_age_group: chr [1:7467] "30-39" "Unknown" "30-39" "50-59" ...

Data visualization

Data visualization in R

  • Using base R functions

  • Using the ggplot2 package \(\leftarrow\) our focus today

  • Using a variety of other packages like lattice, ggvis, etc.

The Grammar of Graphics

  • Visualisation concept created by Wilkinson (1999)
    • to define the basic elements of a statistical graphic
  • Adapted for R by Wickham (2009) who created the ggplot2 package
    • consistent and compact syntax to describe statistical graphics
    • highly modular as it breaks up graphs into semantic components
  • Is not a guide which graph to choose and how to convey information best!

Source: https://rpubs.com/timwinke/ggplot2workshop

The Grammar of Graphics - Terminology

A statistical graphic is a…

  • mapping of data
  • to aesthetic attributes (color, size, xy-position)
  • using geometric objects (points, lines, bars)
  • with data being statistically transformed (summarised, log-transformed)
  • and mapped onto a specific facet and coordinate system

Biker age vs. crash hour

  • Which data is used as an input?
  • What geometric objects are chosen for visualization?
  • What variables are mapped onto which attributes?
  • What type of scales are used to map data to aesthetics?
  • Are the variables statistically transformed before plotting?

Biker age vs. crash hour - code

Altering features

  • How did the plot change?
  • Are these changes based on data (i.e. can be mapped to variables in the dataset) or changes in preferences for geometric objects?

Altering features - code

More alterations

  • How did the plot change?
  • Are these changes based on data (i.e. can be mapped to variables in the dataset) or changes in preferences for geometric objects?

More alterations - code

Anatomy of ggplots

ggplot(data = [dataframe], aes(x = [var_x], y = [var_y], 
       color = [var_for_color], fill = [var_for_fill], 
       shape = [var_for_shape])) +
    geom_[some_geom] +
    ... # other options

Histograms

Boxplots

Barplots

Segmented barplots

Segmented barplots - proportions

More ggplot2 resources

  • Visit http://docs.ggplot2.org/current/ for documentation on the current version of the ggplot2 package. It’s full of examples!

  • Refer to the ggplot2 cheatsheet.

Data wrangling

Data wrangling in R

  • Using base R functions

  • Using the dplyr package \(\leftarrow\) our focus today

  • Using a variety of other packages like plyr, tidyr, lubridate, etc.

Data wrangling with dplyr

The dplyr package is based on the concepts of functions as verbs that manipulate data frames:

  • filter(): pick rows matching criteria
  • select(): pick columns by name
  • rename(): rename specific columns
  • arrange(): reorder rows
  • mutate(): add new variables
  • transmute(): create new data frame with variables
  • sample_n() / sample_frac(): randomly sample rows
  • summarise(): reduce variables to values

dplyr rules

  • First argument is a data frame
  • Subsequent arguments say what to do with data frame
  • Always return a data frame
  • Avoid modify in place

Filter rows with filter()

  • Select a subset of rows in a data frame.
  • Easily filter for many conditions at once.

filter()

for crashes in Durham County

## # A tibble: 340 × 66
##    geo_point        geo_shape bike_race city  bike_pos num_units crash_hour
##    <chr>            <chr>     <chr>     <chr> <chr>        <dbl>      <dbl>
##  1 35.9935571162, … "{\"type… Black     Durh… Non-Roa…         2         18
##  2 35.9915271145, … "{\"type… White     Durh… Travel …         2          9
##  3 35.9903871139, … "{\"type… Black     Durh… Non-Roa…         2         16
##  4 35.9966271172, … "{\"type… Black     Durh… Unknown          2         18
##  5 35.9899271152, … "{\"type… Black     Durh… Travel …         2         18
##  6 36.0306171247, … "{\"type… Black     Durh… Travel …         2         15
##  7 36.0106001186, … "{\"type… White     Durh… Sidewal…         2          9
##  8 35.992633116, -… "{\"type… Black     Durh… Sidewal…         2         11
##  9 36.0773371334, … "{\"type… Hispanic  Durh… Non-Roa…         2         12
## 10 35.9934071161, … "{\"type… Black     Durh… Travel …         2         13
## # ℹ 330 more rows
## # ℹ 59 more variables: locality <chr>, bike_sex <chr>, drvr_veh_typ <chr>,
## #   num_bikes_no <dbl>, bike_alc_drg <chr>, num_bikes_bi <dbl>,
## #   rte_invd_cd <dbl>, drvr_race <chr>, workzone <chr>,
## #   num_bikes_ci <dbl>, bike_age_group <chr>, crash_type <chr>,
## #   rd_defects <chr>, crash_alcoh <chr>, bike_alcoho <chr>,
## #   rd_conditio <chr>, dstnc_mi_frm <dbl>, rural_urban <chr>, …

filter()

for crashes in Durham County where biker was < 10 yrs old

## # A tibble: 27 × 66
##    geo_point        geo_shape bike_race city  bike_pos num_units crash_hour
##    <chr>            <chr>     <chr>     <chr> <chr>        <dbl>      <dbl>
##  1 35.9935571162, … "{\"type… Black     Durh… Non-Roa…         2         18
##  2 35.9966271172, … "{\"type… Black     Durh… Unknown          2         18
##  3 35.9625371071, … "{\"type… Black     Durh… Travel …         2         19
##  4 35.9783271161, … "{\"type… Black     Durh… Non-Roa…         2         16
##  5 36.0011901184, … "{\"type… Black     Durh… Travel …         2         17
##  6 36.0337971252, … "{\"type… Hispanic  Durh… Unknown          2         12
##  7 35.9394941044, … "{\"type… Black     Durh… Unknown          2         17
##  8 36.019327123, -… "{\"type… Black     Durh… Drivewa…         2         20
##  9 36.0027501191, … "{\"type… Black     Durh… Drivewa…         2         13
## 10 35.9917211153, … "{\"type… Black     Durh… Travel …         2         18
## # ℹ 17 more rows
## # ℹ 59 more variables: locality <chr>, bike_sex <chr>, drvr_veh_typ <chr>,
## #   num_bikes_no <dbl>, bike_alc_drg <chr>, num_bikes_bi <dbl>,
## #   rte_invd_cd <dbl>, drvr_race <chr>, workzone <chr>,
## #   num_bikes_ci <dbl>, bike_age_group <chr>, crash_type <chr>,
## #   rd_defects <chr>, crash_alcoh <chr>, bike_alcoho <chr>,
## #   rd_conditio <chr>, dstnc_mi_frm <dbl>, rural_urban <chr>, …

Commonly used logical operators in R

operator definition
< less than
<= less than or equal to
> greater than
>= greater than or equal to
== exactly equal to
!= not equal to
x | y x OR y
x & y x AND y

Commonly used logical operators in R

operator definition
is.na(x) test if x is NA
!is.na(x) test if x is not NA
x %in% y test if x is in y
!(x %in% y) test if x is not in y
!x not x

Aside: real data is messy!

What in the world does a bike_age_group of 10-Jun or 15-Nov mean?

## # A tibble: 12 × 2
##    bike_age_group crash_count
##    <chr>                <int>
##  1 0-5                     86
##  2 11-15                  933
##  3 16-19                  794
##  4 20-24                  910
##  5 25-29                  578
##  6 30-39                  881
##  7 40-49                 1144
##  8 50-59                 1013
##  9 6-10                   537
## 10 60-69                  382
## 11 70+                     96
## 12 Unknown                113

Careful data scientists clean up their data first!

  • We’re going to need to do some text parsing to clean up these data
    • 10-Jun should be 6-10
    • 15-Nov should be 11-15
  • New R package: stringr

Install and load: stringr

  • Install:
  • Load:
  • Package reference: Most R packages come with a vignette that describe in detail what each function does and how to use them, they’re incredibly useful resources (in addition to other worked out examples on the web) https://cran.r-project.org/web/packages/stringr/vignettes/stringr.html

Replace with str_replace() and add new variables with mutate()

  • Remember we want to do the following in the bike_age_group variable: 10-Jun should be 6-10 and 15-Nov should be 11-15
  • Note that we’re overwriting existing data and columns, so be careful!
    • But remember, it’s easy to revert if you make a mistake since we didn’t touch the raw data, we can always reload it and start over

Check before you move on

Always check your changes and confirm code did what you wanted it to do

## # A tibble: 12 × 2
##    bike_age_group count
##    <chr>          <int>
##  1 0-5               86
##  2 11-15            933
##  3 16-19            794
##  4 20-24            910
##  5 25-29            578
##  6 30-39            881
##  7 40-49           1144
##  8 50-59           1013
##  9 6-10             537
## 10 60-69            382
## 11 70+               96
## 12 Unknown          113

slice() for certain row numbers

First five

## # A tibble: 5 × 66
##   geo_point         geo_shape bike_race city  bike_pos num_units crash_hour
##   <chr>             <chr>     <chr>     <chr> <chr>        <dbl>      <dbl>
## 1 35.3336070056, -… "{\"type… Black     None… Bike La…         2          6
## 2 36.3151872016, -… "{\"type… Black     Hend… Travel …         2         20
## 3 35.5246969313, -… "{\"type… White     None… Travel …         2         18
## 4 34.3314967628, -… "{\"type… Black     Whit… Unknown          2         18
## 5 34.2347367682, -… "{\"type… White     Wilm… Sidewal…         2         13
## # ℹ 59 more variables: locality <chr>, bike_sex <chr>, drvr_veh_typ <chr>,
## #   num_bikes_no <dbl>, bike_alc_drg <chr>, num_bikes_bi <dbl>,
## #   rte_invd_cd <dbl>, drvr_race <chr>, workzone <chr>,
## #   num_bikes_ci <dbl>, bike_age_group <chr>, crash_type <chr>,
## #   rd_defects <chr>, crash_alcoh <chr>, bike_alcoho <chr>,
## #   rd_conditio <chr>, dstnc_mi_frm <dbl>, rural_urban <chr>,
## #   hit_run <chr>, crash_date <chr>, num_bikes_ui <dbl>, …

slice() for certain row numbers

Last five

## # A tibble: 5 × 66
##   geo_point         geo_shape bike_race city  bike_pos num_units crash_hour
##   <chr>             <chr>     <chr>     <chr> <chr>        <dbl>      <dbl>
## 1 35.9642570698, -… "{\"type… Black     High… Travel …         2         17
## 2 34.249566771, -7… "{\"type… Black     Wilm… Travel …         2         22
## 3 35.269592006, -7… "{\"type… Black     Kins… Travel …         2         13
## 4 35.0222009072, -… "{\"type… White     Faye… Travel …         2         21
## 5 34.7845528978, -… "{\"type… White     None… Travel …         3          6
## # ℹ 59 more variables: locality <chr>, bike_sex <chr>, drvr_veh_typ <chr>,
## #   num_bikes_no <dbl>, bike_alc_drg <chr>, num_bikes_bi <dbl>,
## #   rte_invd_cd <dbl>, drvr_race <chr>, workzone <chr>,
## #   num_bikes_ci <dbl>, bike_age_group <chr>, crash_type <chr>,
## #   rd_defects <chr>, crash_alcoh <chr>, bike_alcoho <chr>,
## #   rd_conditio <chr>, dstnc_mi_frm <dbl>, rural_urban <chr>,
## #   hit_run <chr>, crash_date <chr>, num_bikes_ui <dbl>, …

select() to keep only the variables you mention

##                       hit_run
## crash_location           No  Yes
##   Intersection         2878  352
##   Intersection-Related  369   72
##   Non-Intersection     2876  587
##   Non-Roadway           281   38
##   Unknown Location        3    7

or select()to exclude variables

## # A tibble: 7,467 × 65
##    geo_point        geo_shape bike_race city  bike_pos num_units crash_hour
##    <chr>            <chr>     <chr>     <chr> <chr>        <dbl>      <dbl>
##  1 35.3336070056, … "{\"type… Black     None… Bike La…         2          6
##  2 36.3151872016, … "{\"type… Black     Hend… Travel …         2         20
##  3 35.5246969313, … "{\"type… White     None… Travel …         2         18
##  4 34.3314967628, … "{\"type… Black     Whit… Unknown          2         18
##  5 34.2347367682, … "{\"type… White     Wilm… Sidewal…         2         13
##  6 34.7061968304, … "{\"type… Native A… None… Travel …         2         17
##  7 34.912756854, -… "{\"type… White     None… Bike La…         2         17
##  8 35.7759970789, … "{\"type… Black     Rale… Unknown          2          7
##  9 34.3486067664, … "{\"type… Black     Whit… Unknown          2         15
## 10 35.1149669893, … "{\"type… Black     New … Travel …         2          2
## # ℹ 7,457 more rows
## # ℹ 58 more variables: locality <chr>, bike_sex <chr>, drvr_veh_typ <chr>,
## #   num_bikes_no <dbl>, bike_alc_drg <chr>, num_bikes_bi <dbl>,
## #   rte_invd_cd <dbl>, drvr_race <chr>, workzone <chr>,
## #   num_bikes_ci <dbl>, bike_age_group <chr>, crash_type <chr>,
## #   rd_defects <chr>, crash_alcoh <chr>, bike_alcoho <chr>,
## #   rd_conditio <chr>, dstnc_mi_frm <dbl>, rural_urban <chr>, …

rename() specific columns

Correct typos and rename to make variable names shorter and/or more informative

  • Original names:
##  [1] "geo_point"      "geo_shape"      "bike_race"      "city"          
##  [5] "bike_pos"       "num_units"      "crash_hour"     "locality"      
##  [9] "bike_sex"       "drvr_veh_typ"   "num_bikes_no"   "bike_alc_drg"  
## [13] "num_bikes_bi"   "rte_invd_cd"    "drvr_race"      "workzone"      
## [17] "num_bikes_ci"   "bike_age_group" "crash_type"     "rd_defects"    
## [21] "crash_alcoh"    "bike_alcoho"    "rd_conditio"    "dstnc_mi_frm"  
## [25] "rural_urban"    "hit_run"        "crash_date"     "num_bikes_ui"  
## [29] "crash_time"     "drvr_sex"       "drvr_alcoho"    "developmen"    
## [33] "crash_sevr"     "ambulance_req"  "drvr_injury"    "object_id"     
## [37] "crash_month"    "num_bikes_ki"   "rd_characte"    "region"        
## [41] "bike_dir"       "traff_cntrl"    "crash_day"      "crash_location"
## [45] "bike_age"       "num_bikes_to"   "rd_config"      "num_lanes"     
## [49] "num_bikes_ai"   "drvr_alc_drg"   "on_road"        "rd_surface"    
## [53] "towrd_rd"       "rd_feature"     "crash_grp"      "rd_class"      
## [57] "bike_injury"    "county"         "drvr_age"       "weather"       
## [61] "frm_rd"         "drvr_est_spd"   "speed_limit"    "crash_year"    
## [65] "light_cond"     "drvr_age_group"
  • Rename Speed_Limi to Speed_Limit:

Check before you move on

Always check your changes and confirm code did what you wanted it to do

##  [1] "geo_point"      "geo_shape"      "bike_race"      "city"          
##  [5] "bike_pos"       "num_units"      "crash_hour"     "locality"      
##  [9] "bike_sex"       "drvr_veh_typ"   "num_bikes_no"   "bike_alc_drg"  
## [13] "num_bikes_bi"   "rte_invd_cd"    "drvr_race"      "workzone"      
## [17] "num_bikes_ci"   "bike_age_group" "crash_type"     "rd_defects"    
## [21] "crash_alcoh"    "bike_alcoho"    "rd_conditio"    "dstnc_mi_frm"  
## [25] "rural_urban"    "hit_run"        "crash_date"     "num_bikes_ui"  
## [29] "crash_time"     "drvr_sex"       "drvr_alcoho"    "developmen"    
## [33] "crash_sevr"     "ambulance_req"  "drvr_injury"    "object_id"     
## [37] "crash_month"    "num_bikes_ki"   "rd_characte"    "region"        
## [41] "bike_dir"       "traff_cntrl"    "crash_day"      "crash_location"
## [45] "bike_age"       "num_bikes_to"   "rd_config"      "num_lanes"     
## [49] "num_bikes_ai"   "drvr_alc_drg"   "on_road"        "rd_surface"    
## [53] "towrd_rd"       "rd_feature"     "crash_grp"      "rd_class"      
## [57] "bike_injury"    "county"         "drvr_age"       "weather"       
## [61] "frm_rd"         "drvr_est_spd"   "speed_limit"    "crash_year"    
## [65] "light_cond"     "drvr_age_group"

summarise() in a new data frame

## # A tibble: 12 × 2
##    bike_age_group crash_count
##    <chr>                <int>
##  1 0-5                     86
##  2 70+                     96
##  3 Unknown                113
##  4 60-69                  382
##  5 6-10                   537
##  6 25-29                  578
##  7 16-19                  794
##  8 30-39                  881
##  9 20-24                  910
## 10 11-15                  933
## 11 50-59                 1013
## 12 40-49                 1144

and arrange() to order rows

## # A tibble: 12 × 2
##    bike_age_group crash_count
##    <chr>                <int>
##  1 40-49                 1144
##  2 50-59                 1013
##  3 11-15                  933
##  4 20-24                  910
##  5 30-39                  881
##  6 16-19                  794
##  7 25-29                  578
##  8 6-10                   537
##  9 60-69                  382
## 10 Unknown                113
## 11 70+                     96
## 12 0-5                     86

Select rows with sample_n() or sample_frac()

  • sample_n(): randomly sample 5 observations
## [1]  5 66
  • sample_frac(): randomly sample 20% of observations
## [1] 1493   66

More dplyr resources

  • Visit https://cran.r-project.org/web/packages/dplyr/vignettes/introduction.html for the package vignette.

  • Refer to the dplyr cheatsheet.

Basic R syntax

Few important R syntax notes

For when not working with dplyr or ggplot2

  • Refer to a variable in a dataset as bike$crash_location

  • Access any element in a dataframe using square brackets

## # A tibble: 1 × 1
##   bike_pos                  
##   <chr>                     
## 1 Bike Lane / Paved Shoulder
- For all observations in row 1: `bike[1, ]`
- For all observations in column 5: `bike[, 5]`

What’s next?

Want more R?

  • Local install
    • R: https://cran.r-project.org/
    • RStudio: https://www.rstudio.com/products/RStudio/#Desktop
  • Resources for learning R:
    • Coursera
    • DataCamp
    • Many many online demos, resources, examples, as well as books
  • Debugging R errors:
  • Keeping up with what’s new in R land:

Exercise

Your turn

Create a new dataframe that doesn’t include observations where bike_injury = Injury since it’s not clear what this means.

This new dataframe also should include observations in Durham, and where the biker is a teenager (13 to 19 years, inclusive).

Create a visualization that will help answer whether facing traffic or riding with traffic (Bike_Dir) is more dangerous in bike crashes for teenagers in Durham, based on the bike_injury variable.