library(tidyverse)
library(lubridate)
library(forcats)
library(nycflights13)
# Load flights into your environment
data(flights)DATA 101 — Homework 4: Dates, Factors & Missing Data
Instructions
This homework assignment evaluates your ability to work with Dates (lubridate), Factors (forcats), and Missing Data (NA) in R.
You will analyze the flights dataset from the nycflights13 package, which contains records for all 336,776 commercial flights that departed from New York City (JFK, LGA, EWR) in 2013.
Setup and Libraries
Run the chunk below to load the required tidyverse packages and the flights dataset. If you have not yet installed nycflights13, run install.packages("nycflights13") in your R console first.
Inspect the Dataset
# Inspect the dataset structure
glimpse(flights)Rows: 336,776
Columns: 19
$ year <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2…
$ month <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ day <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ dep_time <int> 517, 533, 542, 544, 554, 554, 555, 557, 557, 558, 558, …
$ sched_dep_time <int> 515, 529, 540, 545, 600, 558, 600, 600, 600, 600, 600, …
$ dep_delay <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2, -2, -1…
$ arr_time <int> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 753, 849,…
$ sched_arr_time <int> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 745, 851,…
$ arr_delay <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -3, 7, -1…
$ carrier <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV", "B6", "…
$ flight <int> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79, 301, 4…
$ tailnum <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN", "N394…
$ origin <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR", "LGA",…
$ dest <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL", "IAD",…
$ air_time <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138, 149, 1…
$ distance <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 944, 733, …
$ hour <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6…
$ minute <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0…
$ time_hour <dttm> 2013-01-01 05:00:00, 2013-01-01 05:00:00, 2013-01-01 0…
Notice that year, month, day, and dep_time are stored in separate numeric columns, carrier is a plain character string (<chr>), and several columns contain missing values (NA).
Question 1: Creating Datetimes with make_datetime()
Create a new column in flights called dep_datetime that combines year, month, day, and the departure time into a proper POSIXct datetime object using make_datetime().
Hint on dep_time: Times are recorded as integers like 517 (meaning 05:17) or 1830 (meaning 18:30). You can extract the hour using integer division %/% 100 and the minute using the modulus operator %% 100.
Display the first 5 rows showing year, month, day, dep_time, and your new dep_datetime column.
# Your code here:
flights <- flights %>%
mutate(dep_datetime = make_datetime(
year, month, day,
hour = dep_time %/% 100,
min = dep_time %% 100
))
flights %>%
select(year, month, day, dep_time, dep_datetime) %>%
head(5)# A tibble: 5 × 5
year month day dep_time dep_datetime
<int> <int> <int> <int> <dttm>
1 2013 1 1 517 2013-01-01 05:17:00
2 2013 1 1 533 2013-01-01 05:33:00
3 2013 1 1 542 2013-01-01 05:42:00
4 2013 1 1 544 2013-01-01 05:44:00
5 2013 1 1 554 2013-01-01 05:54:00
Question 2: Extracting Components & Filtering with month()
Using your new dep_datetime column and lubridate’s month() function, filter the dataset for all flights that departed in June 2013.
How many total flights departed New York City in June?
# Your code here:
june_flights <- flights %>%
filter(month(dep_datetime) == 6)
nrow(june_flights)[1] 27234
Answer: Enter the number of June flights here. 27,234 flights. —
Question 3: Day of the Week Analysis with wday()
Add a new column called dep_wday to the dataset that extracts the day of the week from dep_datetime as an ordered label (e.g., Sunday, Monday, Tuesday…).
Count the number of departures for each day of the week, sorted from most flights to fewest flights. Which day of the week has the fewest scheduled flights leaving NYC?
# Your code here:
flights <- flights %>%
mutate(
dep_wday = wday(dep_datetime, label = TRUE, abbr = FALSE)
)
flights %>%
count(dep_wday, sort = TRUE)# A tibble: 8 × 2
dep_wday n
<ord> <int>
1 Monday 49468
2 Tuesday 49273
3 Wednesday 48858
4 Friday 48703
5 Thursday 48654
6 Sunday 45643
7 Saturday 37922
8 <NA> 8255
Answer: Enter the day of the week with the fewest departures and its flight count here. Saturday has the fewest departure 37,922 —
Question 4: Converting Categorical Variables to Factors
The carrier column records the two-letter airline code (e.g., "UA", "AA", "DL"), but it is currently stored as a character vector.
Convert carrier into a formal factor and display all of its unique levels. How many distinct airlines operated flights out of NYC in 2013?
# Your code here:
flights <- flights %>%
mutate(carrier = factor(carrier))
levels(flights$carrier) [1] "9E" "AA" "AS" "B6" "DL" "EV" "F9" "FL" "HA" "MQ" "OO" "UA" "US" "VX" "WN"
[16] "YV"
length(levels(flights$carrier))[1] 16
Answer: Enter the number of unique airline carriers here. 16 —
Question 5: Collapsing Factor Levels with fct_collapse()
Use fct_collapse() to consolidate airline carriers into four clean categories: * Keep "UA" (United), "AA" (American), and "DL" (Delta) as their own separate levels. * Group all other airlines into a single category labeled "Other".
Generate a frequency count table displaying how many flights belong to each of these 4 carrier categories.
# Your code here:
flights <- flights %>%
mutate(
carrier_group = fct_collapse(
carrier,
United = "UA",
American = "AA",
Delta = "DL",
Other = setdiff(levels(carrier), c("UA", "AA", "DL"))
)
)
flights %>%
count(carrier_group, sort = TRUE)# A tibble: 4 × 2
carrier_group n
<fct> <int>
1 Other 197272
2 United 58665
3 Delta 48110
4 American 32729
Question 6: Auditing Missing Data (NA)
How many flights in the dataset are missing a departure delay (dep_delay == NA)?
In 1–2 sentences, what does a missing departure time or departure delay typically signify for a scheduled commercial flight in the real world?
# Your code here:
sum(is.na(flights$dep_delay))[1] 8255
Answer: Explain what missing departure delay data represents. 8,255 flights are missing departure delay data, likely because they were cancelled or didn’t have a recorded departure time. —
Question 7: Filtering Missing Data & Calculating Averages
- Filter the dataset to include ONLY completed flights (rows where
dep_delayis not missing). Save this cleaned dataset asflights_clean. How many flights remain? - Using
flights_clean, calculate the average departure delay (in minutes) across all completed flights. Round your answer to 2 decimal places.
# Your code here:
flights_clean <- flights %>%
filter(!is.na(dep_delay))
nrow(flights_clean)[1] 328521
flights_clean %>%
summarise(avg_dep_delay = round(mean(dep_delay), 2))# A tibble: 1 × 1
avg_dep_delay
<dbl>
1 12.6
Answer: State the number of completed flights and the average departure delay in minutes. 328,521 completed flights, with an average departure delay of 12.64 minutes.