library(tidyverse)
mpg |>
summarize(
avg_cty = mean(cty),
avg_hwy = mean(hwy),
n_cars = n(),
.by = class
)
## # A tibble: 7 × 4
## class avg_cty avg_hwy n_cars
## <chr> <dbl> <dbl> <int>
## 1 compact 20.1 28.3 47
## 2 midsize 18.8 27.3 41
## 3 suv 13.5 18.1 62
## 4 2seater 15.4 24.8 5
## 5 minivan 15.8 22.4 11
## 6 pickup 13 16.9 33
## 7 subcompact 20.4 28.1 35Week 11: Reshape
[11a] Summarize / Group
Topics
- Calculate summary statistics to describe an entire dataset
- Extract extreme rows using the slice family of functions
- Apply these operations to distinct subgroups within your data
Readings
- R4DS (2E) Section 3.5: Groups
Slides
*Note that you can click the three-line (hamburger) icon on the bottom-left of the slides to access a navigation menu. You can click inside the slides region and press the left and right arrow keys on your keyboard to advance and reverse the slides and animations.
Practice
1) Summarizing Data
Using the mpg dataset (included with the tidyverse), calculate summary statistics for vehicle fuel efficiency.
First, use
summarize()to calculate the overall average city mileage (cty) and highway mileage (hwy). Name these new columnsavg_ctyandavg_hwy.Next, modify your code to calculate these same averages, but grouped by vehicle
classusing the.byargument.Add a third summary column called
n_carsthat counts the number of observations in each class usingn().
Answer key
2) Extracting Extreme Rows
Using the msleep dataset (also included with the tidyverse), find the animals that sleep the most.
First, select just the
name,vore, andsleep_totalcolumns to make the output easier to read.Use
slice_max()to find the 3 animals with the highest total sleep (sleep_total) across the entire dataset.Now, modify your
slice_max()code to find the single animal with the highest total sleep within each feeding type (vore). Remember to use thebyargument instead of.byinside slice functions!
Answer key
# Overall top 3 sleepers msleep |> select(name, vore, sleep_total) |> slice_max(n = 3, order_by = sleep_total) ## # A tibble: 3 × 3 ## name vore sleep_total ## <chr> <chr> <dbl> ## 1 Little brown bat insecti 19.9 ## 2 Big brown bat insecti 19.7 ## 3 Thick-tailed opposum carni 19.4 # Top sleeper per feeding type msleep |> select(name, vore, sleep_total) |> slice_max(n = 1, order_by = sleep_total, by = vore) ## # A tibble: 5 × 3 ## name vore sleep_total ## <chr> <chr> <dbl> ## 1 Thick-tailed opposum carni 19.4 ## 2 North American Opossum omni 18 ## 3 Arctic ground squirrel herbi 16.6 ## 4 Phalanger <NA> 13.7 ## 5 Little brown bat insecti 19.9
3) Grouped Transformations
Let’s calculate how each animal’s sleep compares to others with the exact same diet using a grouped mutate.
Start with the
msleepdataset and usemutate()with the.byargument to group byvore.Calculate a new column called
mean_sleepthat represents the averagesleep_totalfor that specific diet group. (Note: you will need to addna.rm = TRUEinside your mean function since somevorevalues are missing).Calculate a second new column called
diff_sleepthat subtracts the group’smean_sleepfrom the animal’s actualsleep_total.Finally, select the
name,vore,sleep_total,mean_sleep, anddiff_sleepcolumns to view your work.
Answer key
msleep |> mutate( .by = vore, mean_sleep = mean(sleep_total, na.rm = TRUE), diff_sleep = sleep_total - mean_sleep ) |> select(name, vore, sleep_total, mean_sleep, diff_sleep) ## # A tibble: 83 × 5 ## name vore sleep_total mean_sleep diff_sleep ## <chr> <chr> <dbl> <dbl> <dbl> ## 1 Cheetah carni 12.1 10.4 1.72 ## 2 Owl monkey omni 17 10.9 6.07 ## 3 Mountain beaver herbi 14.4 9.51 4.89 ## 4 Greater short-tailed shrew omni 14.9 10.9 3.97 ## 5 Cow herbi 4 9.51 -5.51 ## 6 Three-toed sloth herbi 14.4 9.51 4.89 ## 7 Northern fur seal carni 8.7 10.4 -1.68 ## 8 Vesper mouse <NA> 7 10.2 -3.19 ## 9 Dog carni 10.1 10.4 -0.279 ## 10 Roe deer herbi 3 9.51 -6.51 ## # ℹ 73 more rows
[11b] Lengthen / Widen
Topics
- Identify when “wide” or “long” format is needed
- Reshape wide data into long data using
pivot_longer() - Reshape long data into wide data using
pivot_wider()
Readings
- R4DS (2E) Section 5.3: Lengthening data
- R4DS (2E) Section 5.4: Widening data
Slides
*Note that you can click the three-line (hamburger) icon on the bottom-left of the slides to access a navigation menu. You can click inside the slides region and press the left and right arrow keys on your keyboard to advance and reverse the slides and animations.
Practice
1) Lengthening Data
Using the billboard dataset (included with the tidyr package), reshape the song ranking data from wide to long format.
- The dataset records the chart rank of songs over 76 weeks in columns
wk1throughwk76. - Use
pivot_longer()to collapse these week columns. Use thestarts_with()helper to select them efficiently. - Name the new category column
"week"and the new value column"rank". - Use the
names_prefixandnames_transform = parse_numberarguments to strip the “wk” text and convert the week column into true numbers.
Answer key
library(tidyverse) data("billboard", package = "tidyr") billboard |> pivot_longer( cols = starts_with("wk"), names_to = "week", values_to = "rank", names_prefix = "wk", names_transform = parse_number ) ## # A tibble: 24,092 × 5 ## artist track date.entered week rank ## <chr> <chr> <date> <dbl> <dbl> ## 1 2 Pac Baby Don't Cry (Keep... 2000-02-26 1 87 ## 2 2 Pac Baby Don't Cry (Keep... 2000-02-26 2 82 ## 3 2 Pac Baby Don't Cry (Keep... 2000-02-26 3 72 ## 4 2 Pac Baby Don't Cry (Keep... 2000-02-26 4 77 ## 5 2 Pac Baby Don't Cry (Keep... 2000-02-26 5 87 ## 6 2 Pac Baby Don't Cry (Keep... 2000-02-26 6 94 ## 7 2 Pac Baby Don't Cry (Keep... 2000-02-26 7 99 ## 8 2 Pac Baby Don't Cry (Keep... 2000-02-26 8 NA ## 9 2 Pac Baby Don't Cry (Keep... 2000-02-26 9 NA ## 10 2 Pac Baby Don't Cry (Keep... 2000-02-26 10 NA ## # ℹ 24,082 more rows
2) Widening Data
Using the us_rent_income dataset (included with the tidyr package), reshape the state data from long to wide format so that rent and income are presented side-by-side.
- First, use
select()to keep only theNAME,variable, andestimatecolumns. This prevents issues with duplicate rows caused by other identifiers. - Use
pivot_wider()to create separate columns for each category stored in thevariablecolumn. - Pull the actual numerical values from the
estimatecolumn.
Answer key
data("us_rent_income", package = "tidyr") us_rent_income |> select(NAME, variable, estimate) |> pivot_wider( names_from = variable, values_from = estimate ) ## # A tibble: 52 × 3 ## NAME income rent ## <chr> <dbl> <dbl> ## 1 Alabama 24476 747 ## 2 Alaska 32940 1200 ## 3 Arizona 27517 972 ## 4 Arkansas 23789 709 ## 5 California 29454 1358 ## 6 Colorado 32401 1125 ## 7 Connecticut 35326 1123 ## 8 Delaware 31560 1076 ## 9 District of Columbia 43198 1424 ## 10 Florida 25952 1077 ## # ℹ 42 more rows
3) Pivoting Multiple Columns
Pivoting multiple columns simultaneously is a powerful tool for longitudinal or repeated-measures data. Let’s practice this on a simulated weather dataset.
- First, copy the code below to create the
weatherdataset. - Use
pivot_wider()to flatten this dataset so each station occupies only a single row. - Provide both category columns to the
names_fromargument to combine the season and measurement types. - Separate the combined names using a custom character with the
names_separgument.
weather <- tibble(
station = rep(c("Station1", "Station2"), each = 4),
season = rep(c("summer", "summer", "winter", "winter"), times = 2),
measure = rep(c("temp", "precip"), times = 4),
value = c(85, 2.1, 32, 5.5, 90, 1.8, 40, 6.2)
)Answer key
weather |> pivot_wider( names_from = c(season, measure), values_from = value, names_sep = "_" ) ## # A tibble: 2 × 5 ## station summer_temp summer_precip winter_temp winter_precip ## <chr> <dbl> <dbl> <dbl> <dbl> ## 1 Station1 85 2.1 32 5.5 ## 2 Station2 90 1.8 40 6.2
[11c] Link / Join Data
Topics
- Understand the principles of relational data and keys
- Conceptually differentiate mutating join types
- Perform joins in R using {dplyr} functions
Readings
- R4DS (2E) Chapter 19: Joins
Slides
*Note that you can click the three-line (hamburger) icon on the bottom-left of the slides to access a navigation menu. You can click inside the slides region and press the left and right arrow keys on your keyboard to advance and reverse the slides and animations.
Practice
1) Weather and Delays
To prepare for an analysis of the relationship between weather and departure delays, link the flights and weather datasets (from the nycflights13 package) and add the weather variables to the flights dataset. Treat the following variables as key variables: year, month, day, hour, and origin.
Answer key
library(tidyverse) library(nycflights13) data("flights", package = "nycflights13") data("weather", package = "nycflights13") flights |> left_join(weather, by = join_by(year, month, day, hour, origin)) ## # A tibble: 336,776 × 29 ## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time ## <int> <int> <int> <int> <int> <dbl> <int> <int> ## 1 2013 1 1 517 515 2 830 819 ## 2 2013 1 1 533 529 4 850 830 ## 3 2013 1 1 542 540 2 923 850 ## 4 2013 1 1 544 545 -1 1004 1022 ## 5 2013 1 1 554 600 -6 812 837 ## 6 2013 1 1 554 558 -4 740 728 ## 7 2013 1 1 555 600 -5 913 854 ## 8 2013 1 1 557 600 -3 709 723 ## 9 2013 1 1 557 600 -3 838 846 ## 10 2013 1 1 558 600 -2 753 745 ## # ℹ 336,766 more rows ## # ℹ 21 more variables: arr_delay <dbl>, carrier <chr>, flight <int>, ## # tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, ## # hour <dbl>, minute <dbl>, time_hour.x <dttm>, temp <dbl>, dewp <dbl>, ## # humid <dbl>, wind_dir <dbl>, wind_speed <dbl>, wind_gust <dbl>, ## # precip <dbl>, pressure <dbl>, visib <dbl>, time_hour.y <dttm>
2) Aircraft Specs for Long Hauls
What kind of hardware is flying into Honolulu (HNL)? Retrieve the seating capacity and the manufacturer for every flight that flew to that destination.
Hint: Start by filtering down to flights destined for HNL; then add the manufacturer and seats data for those specific aircraft; then select down to month, day, flight, tailnum, manufacturer, and seats.
Answer key
data("planes", package = "nycflights13") flights |> filter(dest == "HNL") |> left_join(planes, by = "tailnum") |> select(month, day, flight, tailnum, manufacturer, seats) ## # A tibble: 707 × 6 ## month day flight tailnum manufacturer seats ## <int> <int> <int> <chr> <chr> <int> ## 1 1 1 51 N380HA AIRBUS 377 ## 2 1 1 15 N76065 BOEING 292 ## 3 1 2 51 N380HA AIRBUS 377 ## 4 1 2 15 N77066 BOEING 292 ## 5 1 3 51 N380HA AIRBUS 377 ## 6 1 3 15 N76064 BOEING 292 ## 7 1 4 51 N384HA AIRBUS 377 ## 8 1 4 15 N76065 BOEING 292 ## 9 1 5 51 N381HA AIRBUS 377 ## 10 1 5 15 N76065 BOEING 292 ## # ℹ 697 more rows
3) The High-Altitude Filter
Let’s isolate flights traveling to high-altitude territory. Create a dataset that only contains flights that landed at airports located 5,000 feet or higher above sea level.
Hint: Use an inner join to keep only the flights where the destination airport exists in a pre-filtered list of high-altitude airports.
Answer key
data("airports", package = "nycflights13") high_alt_airports <- airports |> filter(alt >= 5000) flights |> select(flight, dest) |> inner_join(high_alt_airports, by = join_by(dest == faa)) ## # A tibble: 7,788 × 9 ## flight dest name lat lon alt tz dst tzone ## <int> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <chr> ## 1 883 DEN Denver Intl 39.9 -105. 5431 -7 A America/Denv… ## 2 1162 DEN Denver Intl 39.9 -105. 5431 -7 A America/Denv… ## 3 477 DEN Denver Intl 39.9 -105. 5431 -7 A America/Denv… ## 4 733 DEN Denver Intl 39.9 -105. 5431 -7 A America/Denv… ## 5 914 DEN Denver Intl 39.9 -105. 5431 -7 A America/Denv… ## 6 835 DEN Denver Intl 39.9 -105. 5431 -7 A America/Denv… ## 7 1741 JAC Jackson Hole Airport 43.6 -111. 6451 -7 A America/Denv… ## 8 1643 DEN Denver Intl 39.9 -105. 5431 -7 A America/Denv… ## 9 1597 EGE Eagle Co Rgnl 39.6 -107. 6540 -7 A America/Denv… ## 10 766 DEN Denver Intl 39.9 -105. 5431 -7 A America/Denv… ## # ℹ 7,778 more rows