Extension: Comparing City and Highway MPG

Andre Thomson

2026-11-08

Source

I extended Patricio Romero’s Exploring Vehicle Fuel Efficiency with Tidyverse vignette. His work uses dplyr and ggplot2 to compare fuel efficiency by vehicle class.

My extension adds tidyr::pivot_longer(). I use it to place city and highway MPG in the same column, then compare both values in one table and chart.

Load the data

Show code
# tidyverse includes dplyr, tidyr, and ggplot2.
# knitr is used to display the summary table.
library(tidyverse)
library(knitr)

# The mpg dataset is included with ggplot2, so no separate CSV is needed.
data("mpg", package = "ggplot2")

Change the table from wide to long

The original data stores city MPG in cty and highway MPG in hwy. I used pivot_longer() so both measurements use one road_type column and one mpg column.

Show code
# Keep the vehicle class and the two MPG columns.
# Rename cty and hwy so the labels are easier to understand.
mpg_long <- mpg |>
  select(class, city = cty, highway = hwy) |>
  # Stack city and highway into one road-type column.
  pivot_longer(
    cols = c(city, highway),
    names_to = "road_type",
    values_to = "mpg"
  ) |>
  mutate(
    class = recode(
      class,
      "2seater" = "Two Seater",
      "compact" = "Compact",
      "midsize" = "Mid-Size",
      "minivan" = "Minivan",
      "pickup" = "Pickup",
      "subcompact" = "Subcompact",
      "suv" = "SUV"
    ),
    road_type = str_to_title(road_type)
  )

mpg_long |>
  slice_head(n = 8) |>
  kable(
    col.names = c("Vehicle class", "Road type", "MPG"),
    caption = "City and highway MPG in a longer table"
  )
City and highway MPG in a longer table
Vehicle class Road type MPG
Compact City 18
Compact Highway 29
Compact City 21
Compact Highway 29
Compact City 20
Compact Highway 31
Compact City 21
Compact Highway 30

The row count changes from 234 to 468 because every vehicle now has one city row and one highway row. No vehicle was added or removed.

Calculate the averages

Show code
# Calculate one average for each vehicle class and road type.
mpg_summary <- mpg_long |>
  group_by(class, road_type) |>
  summarise(
    vehicles = n(),
    average_mpg = round(mean(mpg), 1),
    .groups = "drop"
  ) |>
  arrange(class, road_type)

mpg_summary |>
  kable(
    col.names = c("Vehicle class", "Road type", "Vehicles", "Average MPG"),
    caption = "Average city and highway MPG by vehicle class"
  )
Average city and highway MPG by vehicle class
Vehicle class Road type Vehicles Average MPG
Compact City 47 20.1
Compact Highway 47 28.3
Mid-Size City 41 18.8
Mid-Size Highway 41 27.3
Minivan City 11 15.8
Minivan Highway 11 22.4
Pickup City 33 13.0
Pickup Highway 33 16.9
SUV City 62 13.5
SUV Highway 62 18.1
Subcompact City 35 20.4
Subcompact Highway 35 28.1
Two Seater City 5 15.4
Two Seater Highway 5 24.8

The table shows that every class has a higher highway average than city average. Compact and subcompact vehicles have the highest highway averages in this dataset.

Compare both road types in one chart

Show code
# The two road types use charcoal and orange, with printed values for accessibility.
# The value labels also show the difference without depending only on color.
ggplot(
  mpg_summary,
  aes(
    x = class,
    y = average_mpg,
    fill = road_type
  )
) +
  geom_col(
    position = position_dodge(width = 0.75),
    width = 0.68,
    color = "#333333"
  ) +
  geom_text(
    aes(label = average_mpg),
    position = position_dodge(width = 0.75),
    hjust = -0.15,
    size = 3.2
  ) +
  coord_flip() +
  scale_fill_manual(values = c("City" = "#666666", "Highway" = "#E69F00")) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
  labs(
    title = "Average city and highway MPG by vehicle class",
    x = NULL,
    y = "Average miles per gallon",
    fill = "Road type"
  ) +
  theme_minimal(base_size = 11) +
  theme(panel.grid.major.y = element_blank())
Grouped bar chart comparing average city and highway miles per gallon for seven vehicle classes. Highway MPG is higher for every class.
Figure 1

Summary

My extension adds a new Tidyverse step to the original work. pivot_longer() makes it possible to group city and highway values under one variable. This makes the comparison easier to summarize and graph without writing separate code for each road type.

Sources

AI use

I used ChatGPT and VS Code to help draft, troubleshoot, and organize parts of the code and documentation.