1. Highway Fuel Economy Over the Years, Revisited
library(readr)
if (! file.exists("vehicles.csv.zip"))
download.file("http://www.stat.uiowa.edu/~luke/data/vehicles.csv.zip",
"vehicles.csv.zip")
newmpg <- read_csv("vehicles.csv.zip", guess_max = 100000)
newmpg3 <- filter(newmpg, year <= 2025, year >= 2000) |>
mutate(year = factor(year))
All four approaches, with only minimal tuning for the three new
ones:
alpha <- 0.2
size <- 0.3
thm <- theme_minimal() + theme(text = element_text(size = 16))
library(ggridges)
library(patchwork)
p1 <- ggplot(newmpg3, aes(x = highway08, y = year)) +
geom_point(position = "jitter", size = size, alpha = alpha) +
ylab(NULL) +
thm
p2 <- ggplot(newmpg3, aes(y = highway08, x = year)) +
geom_boxplot() +
thm +
coord_flip()
p3 <- ggplot(newmpg3, aes(y = highway08, x = year)) +
geom_violin() +
thm +
coord_flip()
p4 <- ggplot(newmpg3, aes(x = highway08, y = year)) +
geom_density_ridges() +
thm
(p1 | p2) / (p3 | p4)
## Picking joint bandwidth of 1.43

The three new approaches do a better job of conveying the increase in
fuel economy for the bulk of the vehicles. Both violin and ridgeline
plots show the slight bimodal structure in the early years; box plots
cannot reflect this. Box plots put a high emphasis on the electric
vehicles; this can be reduced by adjusting the point size used. Strip
plots also allow the emerging electric vehicles to be seen. Violin plots
and ridgeline plots do not show these very well as they are still too
small a proportion of the total. The fact that violin plots stop at the
maximum helps somewhat. The current geom_density_ridges
implementation does not do this but could in principle be modified to do
so.
2. Top Fleet Highway Gas Mileages
The following table shows the manufacturers with top five fleet
average highway gas mileage values and the corresponging average city
gas mileages:
library(readr)
if (! file.exists("vehicles.csv.zip"))
download.file("http://www.stat.uiowa.edu/~luke/data/vehicles.csv.zip",
"vehicles.csv.zip")
newmpg <- read_csv("vehicles.csv.zip", guess_max = 100000)
tbl <- filter(newmpg, year == 2025) |>
group_by(make) |>
summarize(avg_hwy = mean(highway08),
avg_cty = mean(city08)) |>
ungroup() |>
slice_max(avg_hwy, n = 5) |>
arrange(desc(avg_hwy))
names(tbl) <- c("Make", "Highway", "City")
kbl <- knitr::kable(tbl, format = "html", digits = 1)
kableExtra::kable_styling(kbl, full_width = FALSE)
|
Make
|
Highway
|
City
|
|
Lucid
|
110.1
|
116.5
|
|
Fiat
|
102.0
|
124.0
|
|
Tesla
|
99.0
|
112.2
|
|
Polestar
|
86.6
|
98.3
|
|
Vinfast
|
73.4
|
77.6
|
3. Top Destinations
The top four destinations are shown in the following table:
top_nyc_dest <- count(flights, dest) |> slice_max(n, n = 4)
kbl <- knitr::kable(top_nyc_dest, format = "html")
kableExtra::kable_styling(kbl, full_width = FALSE)
|
dest
|
n
|
|
ORD
|
17283
|
|
ATL
|
17215
|
|
LAX
|
16174
|
|
BOS
|
15508
|
The flights to these locations can be selected using
semi_join. After using count to compute the
number of flights to each origin/destination the counts for each
destination can be converted to proportion with a grouped
mutate. The resulting faceted bar chart:
top_nyc_dest <- count(flights, dest) |> slice_max(n, n = 4)
semi_join(flights, top_nyc_dest, "dest") |>
count(origin, dest) |>
group_by(dest) |>
mutate(prop = n / sum(n)) |>
ungroup() |>
ggplot() +
geom_col(aes(x = origin, y = prop), fill = "deepskyblue3") +
facet_wrap(~ dest, ncol = 1) +
thm +
labs(x = "Origin", y = "Proportion")

There are no flights from LGA to LAX and few from JFK to either ATL
or ORD.
4. Summer-Only Destinations
fs <- filter(flights, month %in% 6 : 8) |> select(dest) |> unique()
fn <- filter(flights, ! (month %in% 6 : 8)) |> select(dest) |> unique()
summer_only <- anti_join(fs, fn, "dest")
summer_dest <- semi_join(airports, summer_only, c(faa = "dest")) |>
select(faa, name)
flight_counts <- count(flights, dest)
summer_dest <- left_join(summer_dest, flight_counts, c("faa" = "dest"))
There were 3 destinations with flights only in June through
August:
knitr::kable(summer_dest, format = "html") |>
kableExtra::kable_styling(full_width = FALSE)
|
faa
|
name
|
n
|
|
ANC
|
Ted Stevens Anchorage Intl
|
8
|
|
LGA
|
La Guardia
|
1
|
|
TVC
|
Cherry Capital Airport
|
101
|
Apparently there was a flight on US Airways from EWR to LGA on July
27.
5. High Altitude Destinations
The destinations at altitudes above 5,000 feet and the number of
flights in 2013 from New York City to these destinations were:
airports1 <- select(airports, faa, name, alt)
left_join(flights, airports1, c("dest" = "faa")) |>
filter(alt > 5000) |>
count(dest, name, alt) |>
select(FAA = dest, Name = name, Altitude = alt, Flights = n) |>
knitr::kable(format = "html") |>
kableExtra::kable_styling(full_width = FALSE)
|
FAA
|
Name
|
Altitude
|
Flights
|
|
ABQ
|
Albuquerque International Sunport
|
5355
|
254
|
|
DEN
|
Denver Intl
|
5431
|
7266
|
|
EGE
|
Eagle Co Rgnl
|
6540
|
213
|
|
HDN
|
Yampa Valley
|
6602
|
15
|
|
JAC
|
Jackson Hole Airport
|
6451
|
25
|
|
MTJ
|
Montrose Regional Airport
|
5759
|
15
|
LS0tCnRpdGxlOiAiQXNzaWdubWVudCA2IE5vdGVzIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6ICJoaWRlIgotLS0KCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChjb2xsYXBzZSA9IFRSVUUpCmBgYAoKYGBge3IsIGluY2x1ZGUgPSBGQUxTRX0KbGlicmFyeShkcGx5cikKbGlicmFyeShueWNmbGlnaHRzMTMpCmxpYnJhcnkoZ2dwbG90MikKCmBgYAoKCiMjIDEuIEhpZ2h3YXkgRnVlbCBFY29ub215IE92ZXIgdGhlIFllYXJzLCBSZXZpc2l0ZWQKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0V9CmxpYnJhcnkocmVhZHIpCmlmICghIGZpbGUuZXhpc3RzKCJ2ZWhpY2xlcy5jc3YuemlwIikpCiAgICBkb3dubG9hZC5maWxlKCJodHRwOi8vd3d3LnN0YXQudWlvd2EuZWR1L35sdWtlL2RhdGEvdmVoaWNsZXMuY3N2LnppcCIsCiAgICAgICAgICAgICAgICAgICJ2ZWhpY2xlcy5jc3YuemlwIikKbmV3bXBnIDwtIHJlYWRfY3N2KCJ2ZWhpY2xlcy5jc3YuemlwIiwgZ3Vlc3NfbWF4ID0gMTAwMDAwKQpuZXdtcGczIDwtIGZpbHRlcihuZXdtcGcsIHllYXIgPD0gMjAyNSwgeWVhciA+PSAyMDAwKSB8PgogICAgbXV0YXRlKHllYXIgPSBmYWN0b3IoeWVhcikpCmBgYAoKQWxsIGZvdXIgYXBwcm9hY2hlcywgd2l0aCBvbmx5IG1pbmltYWwgdHVuaW5nIGZvciB0aGUgdGhyZWUgbmV3IG9uZXM6CgpgYGB7ciwgZmlnLmhlaWdodCA9IDksIGZpZy53aWR0aCA9IDl9CmFscGhhIDwtIDAuMgpzaXplIDwtIDAuMwp0aG0gPC0gdGhlbWVfbWluaW1hbCgpICsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYpKQpsaWJyYXJ5KGdncmlkZ2VzKQpsaWJyYXJ5KHBhdGNod29yaykKcDEgPC0gZ2dwbG90KG5ld21wZzMsIGFlcyh4ID0gaGlnaHdheTA4LCB5ID0geWVhcikpICsKICAgIGdlb21fcG9pbnQocG9zaXRpb24gPSAiaml0dGVyIiwgc2l6ZSA9IHNpemUsIGFscGhhID0gYWxwaGEpICsKICAgIHlsYWIoTlVMTCkgKwogICAgdGhtCnAyIDwtIGdncGxvdChuZXdtcGczLCBhZXMoeSA9IGhpZ2h3YXkwOCwgeCA9IHllYXIpKSArCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB0aG0gKwogICAgY29vcmRfZmxpcCgpCnAzIDwtIGdncGxvdChuZXdtcGczLCBhZXMoeSA9IGhpZ2h3YXkwOCwgeCA9IHllYXIpKSArCiAgICBnZW9tX3Zpb2xpbigpICsKICAgIHRobSArCiAgICBjb29yZF9mbGlwKCkKcDQgPC0gZ2dwbG90KG5ld21wZzMsIGFlcyh4ID0gaGlnaHdheTA4LCB5ID0geWVhcikpICsKICAgIGdlb21fZGVuc2l0eV9yaWRnZXMoKSArCiAgICB0aG0KCihwMSB8IHAyKSAvIChwMyB8IHA0KQpgYGAKClRoZSB0aHJlZSBuZXcgYXBwcm9hY2hlcyBkbyBhIGJldHRlciBqb2Igb2YgY29udmV5aW5nIHRoZSBpbmNyZWFzZSBpbgpmdWVsIGVjb25vbXkgZm9yIHRoZSBidWxrIG9mIHRoZSB2ZWhpY2xlcy4gQm90aCB2aW9saW4gYW5kIHJpZGdlbGluZQpwbG90cyBzaG93IHRoZSBzbGlnaHQgYmltb2RhbCBzdHJ1Y3R1cmUgaW4gdGhlIGVhcmx5IHllYXJzOyBib3ggcGxvdHMKY2Fubm90IHJlZmxlY3QgdGhpcy4gQm94IHBsb3RzIHB1dCBhIGhpZ2ggZW1waGFzaXMgb24gdGhlIGVsZWN0cmljCnZlaGljbGVzOyB0aGlzIGNhbiBiZSByZWR1Y2VkIGJ5IGFkanVzdGluZyB0aGUgcG9pbnQgc2l6ZSB1c2VkLiAgU3RyaXAKcGxvdHMgYWxzbyBhbGxvdyB0aGUgZW1lcmdpbmcgZWxlY3RyaWMgdmVoaWNsZXMgdG8gYmUgc2Vlbi4gIFZpb2xpbgpwbG90cyBhbmQgcmlkZ2VsaW5lIHBsb3RzIGRvIG5vdCBzaG93IHRoZXNlIHZlcnkgd2VsbCBhcyB0aGV5IGFyZQpzdGlsbCB0b28gc21hbGwgYSBwcm9wb3J0aW9uIG9mIHRoZSB0b3RhbC4gVGhlIGZhY3QgdGhhdCB2aW9saW4gcGxvdHMKc3RvcCBhdCB0aGUgbWF4aW11bSBoZWxwcyBzb21ld2hhdC4gVGhlIGN1cnJlbnQgYGdlb21fZGVuc2l0eV9yaWRnZXNgCmltcGxlbWVudGF0aW9uIGRvZXMgbm90IGRvIHRoaXMgYnV0IGNvdWxkIGluIHByaW5jaXBsZSBiZSBtb2RpZmllZCB0bwpkbyBzby4KCgojIyAyLiBUb3AgRmxlZXQgSGlnaHdheSBHYXMgTWlsZWFnZXMKClRoZSBmb2xsb3dpbmcgdGFibGUgc2hvd3MgdGhlIG1hbnVmYWN0dXJlcnMgd2l0aCB0b3AgZml2ZSBmbGVldAphdmVyYWdlIGhpZ2h3YXkgZ2FzIG1pbGVhZ2UgdmFsdWVzIGFuZCB0aGUgY29ycmVzcG9uZ2luZyBhdmVyYWdlIGNpdHkKZ2FzIG1pbGVhZ2VzOgoKYGBge3IsIG1lc3NhZ2UgPSBGQUxTRX0KbGlicmFyeShyZWFkcikKaWYgKCEgZmlsZS5leGlzdHMoInZlaGljbGVzLmNzdi56aXAiKSkKICAgIGRvd25sb2FkLmZpbGUoImh0dHA6Ly93d3cuc3RhdC51aW93YS5lZHUvfmx1a2UvZGF0YS92ZWhpY2xlcy5jc3YuemlwIiwKICAgICAgICAgICAgICAgICAgInZlaGljbGVzLmNzdi56aXAiKQpuZXdtcGcgPC0gcmVhZF9jc3YoInZlaGljbGVzLmNzdi56aXAiLCBndWVzc19tYXggPSAxMDAwMDApCgp0YmwgPC0gZmlsdGVyKG5ld21wZywgeWVhciA9PSAyMDI1KSB8PgogICAgZ3JvdXBfYnkobWFrZSkgfD4KICAgIHN1bW1hcml6ZShhdmdfaHd5ID0gbWVhbihoaWdod2F5MDgpLAogICAgICAgICAgICAgIGF2Z19jdHkgPSBtZWFuKGNpdHkwOCkpIHw+CiAgICB1bmdyb3VwKCkgfD4KICAgIHNsaWNlX21heChhdmdfaHd5LCBuID0gNSkgfD4KICAgIGFycmFuZ2UoZGVzYyhhdmdfaHd5KSkKbmFtZXModGJsKSA8LSBjKCJNYWtlIiwgIkhpZ2h3YXkiLCAiQ2l0eSIpCmtibCA8LSBrbml0cjo6a2FibGUodGJsLCBmb3JtYXQgPSAiaHRtbCIsIGRpZ2l0cyA9IDEpCmthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoa2JsLCBmdWxsX3dpZHRoID0gRkFMU0UpCmBgYAoKIyMgMy4gVG9wIERlc3RpbmF0aW9ucwoKVGhlIHRvcCBmb3VyIGRlc3RpbmF0aW9ucyBhcmUgc2hvd24gaW4gdGhlIGZvbGxvd2luZyB0YWJsZToKCmBgYHtyfQp0b3BfbnljX2Rlc3QgPC0gY291bnQoZmxpZ2h0cywgZGVzdCkgfD4gc2xpY2VfbWF4KG4sIG4gPSA0KQprYmwgPC0ga25pdHI6OmthYmxlKHRvcF9ueWNfZGVzdCwgZm9ybWF0ID0gImh0bWwiKQprYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGtibCwgZnVsbF93aWR0aCA9IEZBTFNFKQpgYGAKClRoZSBmbGlnaHRzIHRvIHRoZXNlIGxvY2F0aW9ucyBjYW4gYmUgc2VsZWN0ZWQgdXNpbmcgYHNlbWlfam9pbmAuCkFmdGVyIHVzaW5nIGBjb3VudGAgdG8gY29tcHV0ZSB0aGUgbnVtYmVyIG9mIGZsaWdodHMgdG8gZWFjaApvcmlnaW4vZGVzdGluYXRpb24gdGhlIGNvdW50cyBmb3IgZWFjaCBkZXN0aW5hdGlvbiBjYW4gYmUgY29udmVydGVkIHRvCnByb3BvcnRpb24gd2l0aCBhIGdyb3VwZWQgYG11dGF0ZWAuIFRoZSByZXN1bHRpbmcgZmFjZXRlZCBiYXIgY2hhcnQ6CgpgYGB7cn0KdG9wX255Y19kZXN0IDwtIGNvdW50KGZsaWdodHMsIGRlc3QpIHw+IHNsaWNlX21heChuLCBuID0gNCkKCnNlbWlfam9pbihmbGlnaHRzLCB0b3BfbnljX2Rlc3QsICJkZXN0IikgfD4KICAgIGNvdW50KG9yaWdpbiwgZGVzdCkgfD4KICAgIGdyb3VwX2J5KGRlc3QpIHw+CiAgICBtdXRhdGUocHJvcCA9IG4gLyBzdW0obikpIHw+CiAgICB1bmdyb3VwKCkgfD4KICAgIGdncGxvdCgpICsKICAgIGdlb21fY29sKGFlcyh4ID0gb3JpZ2luLCB5ID0gcHJvcCksIGZpbGwgPSAiZGVlcHNreWJsdWUzIikgKwogICAgZmFjZXRfd3JhcCh+IGRlc3QsIG5jb2wgPSAxKSArCiAgICB0aG0gKwogICAgbGFicyh4ID0gIk9yaWdpbiIsIHkgPSAiUHJvcG9ydGlvbiIpCmBgYAoKVGhlcmUgYXJlIG5vIGZsaWdodHMgZnJvbSBMR0EgdG8gTEFYIGFuZCBmZXcgZnJvbSBKRksgdG8gZWl0aGVyIEFUTCBvcgpPUkQuCgoKIyMgNC4gU3VtbWVyLU9ubHkgRGVzdGluYXRpb25zCgpgYGB7cn0KZnMgPC0gZmlsdGVyKGZsaWdodHMsIG1vbnRoICVpbiUgNiA6IDgpIHw+IHNlbGVjdChkZXN0KSB8PiB1bmlxdWUoKQpmbiA8LSBmaWx0ZXIoZmxpZ2h0cywgISAobW9udGggJWluJSA2IDogOCkpIHw+IHNlbGVjdChkZXN0KSB8PiB1bmlxdWUoKQpzdW1tZXJfb25seSA8LSBhbnRpX2pvaW4oZnMsIGZuLCAiZGVzdCIpCnN1bW1lcl9kZXN0IDwtIHNlbWlfam9pbihhaXJwb3J0cywgc3VtbWVyX29ubHksIGMoZmFhID0gImRlc3QiKSkgfD4KICAgc2VsZWN0KGZhYSwgbmFtZSkKZmxpZ2h0X2NvdW50cyA8LSBjb3VudChmbGlnaHRzLCBkZXN0KQpzdW1tZXJfZGVzdCA8LSBsZWZ0X2pvaW4oc3VtbWVyX2Rlc3QsIGZsaWdodF9jb3VudHMsIGMoImZhYSIgPSAiZGVzdCIpKQpgYGAKCmBgYHtyLCBlY2hvID0gRkFMU0V9CnNkMSA8LSBncm91cF9ieShmbGlnaHRzLCBkZXN0KSB8PgogICAgc3VtbWFyaXplKG4gPSBuKCksCgkgICAgICAgICAgc3VtbWVyX29ubHkgPSBhbnkobW9udGggJWluJSA2OjgpICYKCQkJICAgICAgICAgICAgICAgICEgYW55KG1vbnRoIDw9IDUpICYKCQkJCQkJCSEgYW55KG1vbnRoID49IDkpKSB8PgoJdW5ncm91cCgpIHw+CglmaWx0ZXIoc3VtbWVyX29ubHkpIHw+CglsZWZ0X2pvaW4oc2VsZWN0KGFpcnBvcnRzLCBmYWEsIG5hbWUpLCBjKCJkZXN0IiA9ICJmYWEiKSkgfD4KICAgIHNlbGVjdChmYWEgPSBkZXN0LCBuYW1lLCBuKQpyZW1hdHRyIDwtIGZ1bmN0aW9uKHgpIHsgYXR0cmlidXRlcyh4KSA8LSBOVUxMOyB4IH0Kc3RvcGlmbm90KGlkZW50aWNhbChyZW1hdHRyKHN1bW1lcl9kZXN0KSwgcmVtYXR0cihzZDEpKSkKYGBgCgpUaGVyZSB3ZXJlIGByIG5yb3coc3VtbWVyX2Rlc3QpYCBkZXN0aW5hdGlvbnMgd2l0aCBmbGlnaHRzIG9ubHkgaW4KSnVuZSB0aHJvdWdoIEF1Z3VzdDoKCmBgYHtyfQprbml0cjo6a2FibGUoc3VtbWVyX2Rlc3QsIGZvcm1hdCA9ICJodG1sIikgfD4KICAgIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKQpgYGAKCkFwcGFyZW50bHkgdGhlcmUgd2FzIGEgZmxpZ2h0IG9uIFVTIEFpcndheXMgZnJvbSBFV1IgdG8gTEdBIG9uIEp1bHkgMjcuCgoKIyMgNS4gSGlnaCBBbHRpdHVkZSBEZXN0aW5hdGlvbnMKClRoZSBkZXN0aW5hdGlvbnMgYXQgYWx0aXR1ZGVzIGFib3ZlIDUsMDAwIGZlZXQgYW5kIHRoZSBudW1iZXIgb2YKZmxpZ2h0cyBpbiAyMDEzIGZyb20gTmV3IFlvcmsgQ2l0eSB0byB0aGVzZSBkZXN0aW5hdGlvbnMgd2VyZToKCmBgYHtyfQphaXJwb3J0czEgPC0gc2VsZWN0KGFpcnBvcnRzLCBmYWEsIG5hbWUsIGFsdCkKbGVmdF9qb2luKGZsaWdodHMsIGFpcnBvcnRzMSwgYygiZGVzdCIgPSAiZmFhIikpIHw+CiAgICBmaWx0ZXIoYWx0ID4gNTAwMCkgfD4KICAgIGNvdW50KGRlc3QsIG5hbWUsIGFsdCkgfD4KICAgIHNlbGVjdChGQUEgPSBkZXN0LCBOYW1lID0gbmFtZSwgQWx0aXR1ZGUgPSBhbHQsIEZsaWdodHMgPSBuKSB8PgogICAga25pdHI6OmthYmxlKGZvcm1hdCA9ICJodG1sIikgfD4KICAgIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKQpgYGAK