This assignment practices data transformation using dplyr verbs and the pipe operator. You’ll work with the nycflights13 dataset to answer questions about flight delays.
Setup
# Assignment 2: Data Transformation# Your Name# Datelibrary(tidyverse)library(nycflights13)# If you haven't installed nycflights13:# install.packages("nycflights13")
Part 1: Filtering and Arranging (25 points)
Task 1.1
Find all flights that departed from JFK in June and were delayed by more than 1 hour. How many flights meet these criteria?
dep_delay <= 0 captures both on-time (0) and early (negative) departures. A common mistake here is using dest == "LAX" | dest == "SFO" instead of dest %in% c("LAX", "SFO"). Both work, but %in% is cleaner when checking one variable against multiple values.
# A tibble: 336,776 × 7
carrier origin dest dep_delay arr_delay delay_diff dep_delay_hrs
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 UA EWR IAH 2 11 9 0.0333
2 UA LGA IAH 4 20 16 0.0667
3 AA JFK MIA 2 33 31 0.0333
4 B6 JFK BQN -1 -18 -17 -0.0167
5 DL LGA ATL -6 -25 -19 -0.1
6 UA EWR ORD -4 12 16 -0.0667
7 B6 EWR FLL -5 19 24 -0.0833
8 EV LGA IAD -3 -14 -11 -0.05
9 B6 JFK MCO -3 -8 -5 -0.05
10 AA LGA ORD -2 8 10 -0.0333
# ℹ 336,766 more rows
Task 2.3
What does a positive delay_diff mean? What does a negative value mean? Answer in a comment, then find a flight that “made up time” (arrived less delayed than it departed).
NoteAnswer
Tip
This builds on Tasks 2.1 and 2.2 — delay_diff must exist in flights_subset before running this.
# A positive delay_diff means the flight arrived MORE delayed than it departed —# it lost additional time in the air (e.g., circling, headwinds).## A negative delay_diff means the flight "made up time" — it arrived# less delayed than it departed (e.g., favorable tailwinds, shorter route).flights_subset |>filter(dep_delay >0, delay_diff <0) |>arrange(delay_diff)
# A tibble: 83,728 × 7
carrier origin dest dep_delay arr_delay delay_diff dep_delay_hrs
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 EV EWR JAX 235 126 -109 3.92
2 HA JFK HNL 60 -27 -87 1
3 HA JFK HNL 206 126 -80 3.43
4 DL JFK SFO 17 -62 -79 0.283
5 HA JFK HNL 24 -52 -76 0.4
6 UA EWR SNA 48 -26 -74 0.8
7 UA EWR SFO 34 -40 -74 0.567
8 UA EWR SFO 31 -42 -73 0.517
9 DL JFK LAX 9 -63 -72 0.15
10 UA EWR LAX 19 -53 -72 0.317
# ℹ 83,718 more rows
Part 3: Grouped Summaries (30 points)
Task 3.1
Calculate the average departure delay for each carrier. Which carrier has the worst average delay?
# A tibble: 16 × 2
carrier avg_dep_delay
<chr> <dbl>
1 F9 20.2
2 EV 20.0
3 YV 19.0
4 FL 18.7
5 WN 17.7
6 9E 16.7
7 B6 13.0
8 VX 12.9
9 OO 12.6
10 UA 12.1
11 MQ 10.6
12 DL 9.26
13 AA 8.59
14 AS 5.80
15 HA 4.90
16 US 3.78
# Frontier Airlines (F9) has the worst average departure delay.# na.rm = TRUE is essential — without it, any carrier with even one# missing value returns NA for the whole mean.
Task 3.2
Calculate the average departure delay for each origin airport, by month. Which month is the worst for delays at each airport?
# A tibble: 29 × 3
dest mean_arr_delay n_flights
<chr> <dbl> <int>
1 BQN 10.9 295
2 ATL 10.5 102
3 SAT 7.69 323
4 MIA 6.66 1548
5 CLE 6.41 1863
6 ORD 6.07 6744
7 SEA 5.83 1101
8 PBI 5.41 1825
9 FLL 5.25 2376
10 DEN 5.16 3737
# ℹ 19 more rows
A common mistake is putting filter(n_flights >= 100)beforesummarize() — at that point, n_flights doesn’t exist yet. The filter on a summary variable always has to come after summarize().
Note: we don’t need na.rm = TRUE inside mean() here because filter(!is.na(arr_delay)) already removed the missing rows. Both approaches work, but the explicit filter step makes the cleaning visible.