Skip to content

Latest commit

 

History

History
369 lines (257 loc) · 11.3 KB

File metadata and controls

369 lines (257 loc) · 11.3 KB

Tutorial 1: Data Manipulation and Visualization

SPOLIER ALERT!

All code is provided in this document. It would be best if you tried to write the code without this document and then used it for reference as necessary.

Overview

This week you practiced tracing a dataset's origin. This week you get your hands dirty inside the data: wrangling it with dplyr verbs and turning it into plots with ggplot2. In this 45-minute activity you will rotate through three short stations built around two classic, built-in R datasets: penguins (from the palmerpenguins package) and flights (from the nycflights13 package). At each station you will copy and paste ready-made R code into RStudio, run it, and read the console output and plots. Then you will record what trend or pattern you noticed in writing/reflection.md.

By the end of this activity, you should be comfortable using filter(), select(), mutate(), arrange(), group_by()/summarize(), basic missing value handling, and ggplot2 to explore a real dataset - and you will have an optional Shiny app to keep exploring on your own.

--- --- --- --- --- --- --- --- ---

What You Will Learn

By the end of this activity, you will be able to:

  1. Wrangle data with dplyr - use filter(), select(), mutate(), arrange(), and group_by()/summarize() to answer questions about a dataset
  2. Handle missing values - detect (is.na(), sum(), colSums()) and remove (na.omit(), drop_na()) missing values before summarizing
  3. Join related tables - combine two datasets that share a common column with left_join()
  4. Visualize trends with ggplot2 - build scatter plots, boxplots, bar charts, and histograms, and use color/faceting to compare groups
  5. Read plots critically - describe, in writing, what a plot does and does not show

Note: You do not need to finish every reflection question during class. Anything unfinished should be completed as homework and submitted before the deadline in the main README.

--- --- --- --- --- --- --- --- ---

Before You Start

In the given code in src/ the below code has been added to make sure the required packages are installed. If a dependency is not already installed, then the code will automatically make the installation for you. How convenient, right?!

if (!require('tidyverse')) install.packages('tidyverse')
if (!require('palmerpenguins')) install.packages('palmerpenguins')
if (!require('nycflights13')) install.packages('nycflights13')

Note: You only need to install a dependency once on your computer. However you must load the code when execute it.

The added code to each of your scrips will also clear out the variables and left-overs variables from previous code executions.

--- --- --- --- --- --- --- --- ---

Station 1: Palmer Penguins - Wrangling Basics

File: src/station_01_penguins_wrangling/explore_penguins_wrangling.R Data: penguins (built into the palmerpenguins package)

What Is This Penguin Data?!

The penguins dataset comes from a real research project at Palmer Station, Antarctica: researchers measured bill length, bill depth, flipper length, and body mass for three penguin species (Adelie, Chinstrap, Gentoo) across three islands. A few measurements are missing because not every penguin could be fully measured in the field.

Step 1: Load the libraries

Replace # TODO: Load the tidyverse and palmerpenguins libraries with:

library(tidyverse)
library(palmerpenguins)

Step 2: Preview the data

Replace # TODO: Preview the structure and first few rows of the penguins data with:

str(penguins)
head(penguins)

Step 3: Check for missing values

Replace # TODO: Count total missing values, and missing values per column with:

sum(is.na(penguins))
colSums(is.na(penguins))

Step 4: Remove missing values

Replace # TODO: Remove rows with any missing values and save as penguins_clean with:

penguins_clean <- na.omit(penguins)
nrow(penguins)
nrow(penguins_clean)

Step 5: Filter to one species

Replace # TODO: Filter penguins_clean to only Gentoo penguins, save as gentoo with:

gentoo <- penguins_clean %>%
  filter(species == "Gentoo")

Step 6: Add a new column with mutate()

Replace # TODO: Add a new column body_mass_kg (body_mass_g / 1000) using mutate() with:

penguins_clean <- penguins_clean %>%
  mutate(body_mass_kg = round(body_mass_g / 1000, 2))

Step 7: Group and summarize

Replace # TODO: Group by species and summarize average bill length, average body mass (kg), and count of penguins per species with:

penguins_summary <- penguins_clean %>%
  group_by(species) %>%
  summarize(
    avg_bill_length = round(mean(bill_length_mm), 1),
    avg_body_mass_kg = round(mean(body_mass_kg), 2),
    n = n()
  )

penguins_summary

Step 8: Arrange the summary

Replace # TODO: Arrange the summary table in descending order of average body mass with:

penguins_summary %>%
  arrange(desc(avg_body_mass_kg))

Station 1 Wrap-Up Questions (record your answers in writing/reflection.md)

  • What trend did you notice among the three species in average bill length or body mass?
  • How many rows were dropped when you removed missing values, and why does that matter for the summary numbers you calculated?

--- --- --- --- --- --- --- --- ---

Station 2: Palmer Penguins - Visualization

File: src/station_02_penguins_visualization/explore_penguins_visualization.R Data: penguins (built into the palmerpenguins package)

Step 1: Load the libraries

Replace # TODO: Load the tidyverse and palmerpenguins libraries with:

library(tidyverse)
library(palmerpenguins)

Step 2: Remove missing values

Replace # TODO: Remove rows with any missing values and save as penguins_clean with:

penguins_clean <- na.omit(penguins)

Step 3: Scatter plot colored by species

Replace # TODO: Scatter plot of bill_length_mm vs. bill_depth_mm, colored by species with:

ggplot(penguins_clean, aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
  geom_point(size = 2, alpha = 0.7) +
  labs(
    title = "Bill Length vs. Bill Depth by Species",
    x = "Bill Length (mm)", y = "Bill Depth (mm)", color = "Species"
  )

Step 4: Boxplot by species

Replace # TODO: Boxplot of body_mass_g by species with:

ggplot(penguins_clean, aes(x = species, y = body_mass_g, fill = species)) +
  geom_boxplot(alpha = 0.7) +
  labs(title = "Body Mass by Species", x = "Species", y = "Body Mass (g)") +
  theme(legend.position = "none")

Step 5: Bar chart by island

Replace # TODO: Bar chart of the number of penguins observed on each island with:

ggplot(penguins_clean, aes(x = island, fill = species)) +
  geom_bar() +
  labs(title = "Penguins Observed per Island", x = "Island", y = "Count", fill = "Species")

Step 6: Facet by island

Replace # TODO: Facet the bill_length_mm vs. bill_depth_mm scatter plot by island with:

ggplot(penguins_clean, aes(x = bill_length_mm, y = bill_depth_mm, color = species)) +
  geom_point(size = 2, alpha = 0.7) +
  facet_wrap(~ island) +
  labs(
    title = "Bill Length vs. Bill Depth by Species, Faceted by Island",
    x = "Bill Length (mm)", y = "Bill Depth (mm)", color = "Species"
  )

Station 2 Wrap-Up Questions

Please respond in writing/reflection.md.

  • Describe one visual pattern from your scatterplot or boxplot that surprised you or confirmed what you expected.
  • Why might faceting or coloring by species reveal a pattern that the overall summary table from Station 1 hides?

--- --- --- --- --- --- --- --- ---

Station 3: NYC Flights - Wrangling & Visualization

File: src/station_03_nycflights_wrangling_viz/explore_flights.R Data: flights and airlines (built into the nycflights13 package)

Backstory

The flights dataset is every flight that departed New York City airports (JFK, LGA, EWR) in 2013 - over 336,000 rows. The airlines dataset is a small lookup table that maps each two-letter carrier code (e.g. "UA") to its full airline name (e.g. "United Air Lines Inc.").

Step 1: Load the libraries

Replace # TODO: Load the tidyverse and nycflights13 libraries with:

library(tidyverse)
library(nycflights13)

Step 2: Preview the data

Replace # TODO: Preview the structure and first few rows of flights and airlines with:

str(flights)
head(flights)
airlines

Step 3: Check for missing delay values

Replace # TODO: Count total missing values in dep_delay and arr_delay with:

sum(is.na(flights$dep_delay))
sum(is.na(flights$arr_delay))

Step 4: Remove missing delay values

Replace # TODO: Remove rows with missing dep_delay or arr_delay, save as flights_clean with:

flights_clean <- flights %>%
  filter(!is.na(dep_delay), !is.na(arr_delay))

nrow(flights)
nrow(flights_clean)

Step 5: Join with airlines

Replace # TODO: Join flights_clean with airlines by "carrier" to add the full airline name, save as flights_named with:

flights_named <- flights_clean %>%
  left_join(airlines, by = "carrier")

Step 6: Group, summarize, and arrange

Replace # TODO: Group by airline name and summarize average departure delay and number of flights, then arrange from highest to lowest average delay with:

delay_by_airline <- flights_named %>%
  group_by(name) %>%
  summarize(
    avg_dep_delay = round(mean(dep_delay), 1),
    n_flights = n()
  ) %>%
  arrange(desc(avg_dep_delay))

delay_by_airline

Step 7: Bar chart of average delay by airline

Replace # TODO: Bar chart of average departure delay by airline name with:

ggplot(delay_by_airline, aes(x = reorder(name, avg_dep_delay), y = avg_dep_delay)) +
  geom_col(fill = "steelblue") +
  coord_flip() +
  labs(
    title = "Average Departure Delay by Airline (2013)",
    x = "Airline", y = "Average Departure Delay (minutes)"
  )

Step 8: Histogram of arrival delay

Replace # TODO: Histogram of arrival delay (arr_delay) across all flights with:

ggplot(flights_clean, aes(x = arr_delay)) +
  geom_histogram(binwidth = 15, fill = "darkorange", color = "white") +
  coord_cartesian(xlim = c(-60, 180)) +
  labs(
    title = "Distribution of Arrival Delays (2013)",
    x = "Arrival Delay (minutes)", y = "Number of Flights"
  )

Station 3 Wrap-Up Questions

Please respond in writing/reflection.md.

  • Which airline had the highest average departure delay in your table? Was that what you expected?
  • The flights data has missing dep_delay/arr_delay values (these are usually cancelled flights). How did removing them change what your summary and plots can tell you?

--- --- --- --- --- --- --- --- ---

Optional: Keep Exploring with the Shiny App

Once you finish all three stations, open shiny_app/app.R in RStudio and click Run App. Pick a dataset, choose variables and a plot type, and use the Show Code button to see the exact dplyr/ggplot2 code behind whatever you built. See the main README for details.

--- --- --- --- --- --- --- --- ---

Wrap-Up

Finish the General Reflection question in writing/reflection.md, thinking back across all three stations and (if you tried it) the Shiny app.