A complete toolkit for getting country data onto honest maps. Country names rarely line up across data sources ("US", "U.S.", "United States", "United States of America" are one country, but a naive join treats them as four), so 'countryatlas' makes ISO codes the universal join key, and matches names in many languages. It joins indicators from the World Bank, Our World in Data, the European Union's statistical office and any statistical data and metadata exchange service to bundled Natural Earth borders and the 'countrycode' Rosetta stone, recording each value's source, unit and release, and can pin a World Bank release so a result reproduces; treats country-year panels as first class, with dated income groups, regions and group memberships, lags keyed on the year and aggregates that report their coverage; adds analysis helpers (per-capita, inequality, convergence, distribution dynamics, rates, and spatial statistics with multiple-testing control); and draws a full vocabulary of equal-area maps (classed and continuous choropleths, proportional-symbol, spike, bivariate, ternary, value-by-alpha, cartogram, tile-grid, flow, small-multiple, animated, globe and interactive), and can hand its curated tables to 'ggsql' for database-side rendering. Honesty is treated as a feature rather than a slogan: maps state their coverage and source, draw small states rather than dropping them and describe themselves in alt text, classification methods can be compared side by side, and the distortion each projection introduces can be measured and drawn. Heavy spatial dependencies stay optional, and a bundled offline snapshot lets every example, test and vignette run without the network.

Country data from any source, joined on ISO codes and drawn as equal-area maps that state their coverage and source.
🔑 One key for every spelling, in a dozen languages:
library(countryatlas)
d <- data.frame(country = c("Cote d'Ivoire", "Korea, Rep.", "Deutschland", "U.K."))
standardize_country(d, country, add = "iso3c")
#> # A tibble: 4 × 2
#> country iso3c
#> <chr> <chr>
#> 1 Cote d'Ivoire CIV
#> 2 Korea, Rep. KOR
#> 3 Deutschland DEU
#> 4 U.K. GBR
🗺️ An equal-area map with its coverage and source in the caption:
world_map(attach_geometry(world_snapshot$countries), gdp_per_capita)
🕰️ Memberships and income groups as of any date, row by row:
in_group(c("GBR", "GBR"), "EU", origin = "iso3c", as_of = c(2016, 2021))
#> [1] TRUE FALSE
classify_countries(data.frame(iso3c = "VNM", year = c(2026, 2027)), "income")
#> iso3c year income
#> 1 VNM 2026 Lower middle income
#> 2 VNM 2027 Upper middle income
install.packages("countryatlas")library(countryatlas): the bundled world_snapshot and every map
work offline, in Equal Earth.sf backend and every other projection:
install.packages(c("sf", "rnaturalearth", "rnaturalearthdata"))world_data(2020) from the World Bank, or any provider
in country_sources() through fetch_indicator().world_data(2020, vintage = "2024-07").tools::R_user_dir("countryatlas", "cache"); clear_country_cache()
empties it.CURL_CA_BUNDLE at your
organisation’s certificate bundle.The Gallery shows every map verb; the articles cover panels, tracing data to its source and honest maps.