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