| Title: | Join World Bank Data, Country Codes and Maps on the ISO Spine |
|---|---|
| Description: | 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. It generalises a one-call, map-ready table that stitches together 'ggplot2' map geometry, 'WDI' World Bank indicators and the 'countrycode' Rosetta stone; exposes the join machinery for the user's own data; ships curated reference data (metadata, group memberships, an indicator catalogue, flags and currencies); adds analysis helpers (per-capita, regional roll-ups, ranking); and turns one hand-drawn choropleth into a full vocabulary of projected, area-honest maps (binned and quantile choropleths, proportional-symbol, bivariate, cartogram, tile-grid, flow, animated, globe and interactive), and can hand its curated, ISO-reconciled tables to 'ggsql' for database-side spatial rendering. Heavy spatial dependencies stay optional, and a bundled offline snapshot lets every example, test and vignette run without the network. |
| Authors: | Youzhi Yu [aut, cre] |
| Maintainer: | Youzhi Yu <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 2.0.0 |
| Built: | 2026-06-25 08:37:50 UTC |
| Source: | https://github.com/pursuitofdatascience/countryatlas |
Aggregate a country-level value to a coarser grouping, optionally with population-weighted means.
aggregate_regions(data, value, by = "region", fun = "sum", weight = NULL)aggregate_regions(data, value, by = "region", fun = "sum", weight = NULL)
data |
A country-level data frame. |
value |
The value column to aggregate (unquoted). |
by |
Grouping column(s) (character), default |
fun |
Aggregation: |
weight |
Optional weight column (unquoted) for |
A tibble of by plus the aggregated value.
df <- data.frame(iso3c = c("USA", "CAN", "BRA"), region = c("North America", "North America", "Latin America"), gdp = c(21, 1.7, 1.4)) aggregate_regions(df, gdp, fun = "sum")df <- data.frame(iso3c = c("USA", "CAN", "BRA"), region = c("North America", "North America", "Latin America"), gdp = c(21, 1.7, 1.4)) aggregate_regions(df, gdp, fun = "sum")
Given a panel from world_data(2000:2020, ...), animate the choropleth over
year via the optional gganimate package, or fall back to a faceted
small-multiple when it is not installed.
animate_world(data, fill, time = year, projection = "equal_earth", ...)animate_world(data, fill, time = year, projection = "equal_earth", ...)
data |
A panel map-ready frame (polygon or sf) with a |
fill |
The fill column (unquoted). |
time |
The time column (unquoted; default |
projection |
Projection for the sf backend. |
... |
Passed to |
A gganim object (if gganimate is available) or a faceted
ggplot.
## Not run: world_data(2000:2005, c(gdp = "NY.GDP.PCAP.KD")) |> animate_world(gdp) ## End(Not run)## Not run: world_data(2000:2005, c(gdp = "NY.GDP.PCAP.KD")) |> animate_world(gdp) ## End(Not run)
Hand countryatlas's curated, ISO-reconciled, WDI-joined spatial table to
ggsql so it can be charted with DRAW spatial – the
bridge that lets ggsql draw maps of your override-corrected data instead of
its static bundled world. sf geometry is WKB-encoded so ggsql can decode it.
as_ggsql_source( data, name = "countryatlas_world", format = c("duckdb", "parquet", "arrow"), con = NULL, path = NULL, geometry_col = "geometry" )as_ggsql_source( data, name = "countryatlas_world", format = c("duckdb", "parquet", "arrow"), con = NULL, path = NULL, geometry_col = "geometry" )
data |
A map-ready frame (ideally |
name |
The table name to register/write (default |
format |
|
con |
An existing DuckDB |
path |
Output path for |
geometry_col |
Name for the WKB geometry column (default |
Depending on format: a DuckDB connection (with the table written),
a Parquet file path, or a nanoarrow array stream.
## Not run: # Curate in R, render in the database: src <- world_data(2020, geometry = "sf") |> as_ggsql_source(format = "duckdb") ggsql::ggsql_execute(src, world_query(gdp_per_capita)) ## End(Not run)## Not run: # Curate in R, render in the database: src <- world_data(2020, geometry = "sf") |> as_ggsql_source(format = "duckdb") ggsql::ggsql_execute(src, world_query(gdp_per_capita)) ## End(Not run)
The bridge between a one-row-per-country table (e.g. from country_data())
and plotting: bolts polygon or sf geometry onto your data, keyed on
iso3c.
attach_geometry( data, by = "iso3c", geometry = c("polygon", "sf"), scale = "small", region = NULL, projection = "equal_earth", recenter = NULL )attach_geometry( data, by = "iso3c", geometry = c("polygon", "sf"), scale = "small", region = NULL, projection = "equal_earth", recenter = NULL )
data |
A data frame with an |
by |
The join key (default |
geometry |
|
scale |
Natural Earth resolution for the |
region |
Optional region subset (see |
projection, recenter
|
Projection options for the |
For "polygon", a tibble with long/lat/group plus your
columns. For "sf", an sf object.
df <- data.frame(iso3c = c("USA", "CAN"), value = c(1, 2)) if (requireNamespace("maps", quietly = TRUE)) { attach_geometry(df, geometry = "polygon") }df <- data.frame(iso3c = c("USA", "CAN"), value = c(1, 2)) if (requireNamespace("maps", quietly = TRUE)) { attach_geometry(df, geometry = "polygon") }
What is missing, before you trust the map: which countries are unmatched,
the NA rate per indicator, and which World Bank regions / income groups are
under-covered – so a half-empty map is caught before it is published.
audit_coverage(data, indicator = NULL, by = c("region", "income", "continent"))audit_coverage(data, indicator = NULL, by = c("region", "income", "continent"))
data |
A country-level (or map-ready) data frame. |
indicator |
Optional character vector of value columns to report |
by |
Grouping for the coverage breakdown: |
A list with elements unmatched, na_rates and by_group.
audit_coverage(countryatlas::world_snapshot$countries)audit_coverage(countryatlas::world_snapshot$countries)
A 2-D bivariate choropleth with a built-in 2-D legend (via the optional
biscale package), e.g. GDP per capita x life expectancy in one map.
bivariate_map( data, fill_x, fill_y, palette = "GrPink", dim = 3, projection = "equal_earth" )bivariate_map( data, fill_x, fill_y, palette = "GrPink", dim = 3, projection = "equal_earth" )
data |
An |
fill_x, fill_y
|
The two value columns (unquoted). |
palette |
A |
dim |
Bivariate dimension (2 or 3, default 3). |
projection |
Projection. |
A ggplot object (the map; combine with biscale::bi_legend() for a
standalone legend).
## Not run: world_data(2020, c(gdp = "NY.GDP.PCAP.KD", life = "SP.DYN.LE00.IN"), geometry = "sf") |> bivariate_map(gdp, life) ## End(Not run)## Not run: world_data(2020, c(gdp = "NY.GDP.PCAP.KD", life = "SP.DYN.LE00.IN"), geometry = "sf") |> bivariate_map(gdp, life) ## End(Not run)
Plots sized circles at country centroids – the right idiom for totals (population, total emissions, total GDP), which a choropleth misrepresents because big values hide in small countries and vice versa.
bubble_map( data, size, color = NULL, projection = "equal_earth", backend = c("polygon", "sf"), max_size = 18, alpha = 0.7 )bubble_map( data, size, color = NULL, projection = "equal_earth", backend = c("polygon", "sf"), max_size = 18, alpha = 0.7 )
data |
A country-level frame with |
size |
The column controlling bubble size (unquoted). |
color |
Optional column controlling bubble colour (unquoted). |
projection |
Projection for the base map (sf path). |
backend |
|
max_size |
Largest bubble size. |
alpha |
Bubble transparency. |
A ggplot object.
snap <- countryatlas::world_snapshot$countries if (requireNamespace("maps", quietly = TRUE)) { bubble_map(snap, population) }snap <- countryatlas::world_snapshot$countries if (requireNamespace("maps", quietly = TRUE)) { bubble_map(snap, population) }
Resizes countries by weight (population, GDP, ...) via the optional
cartogram package, defeating the "big empty countries dominate the eye"
bias of world choropleths.
cartogram_map( data, weight, type = c("contiguous", "dorling", "noncontiguous"), fill = NULL, projection = "equal_earth" )cartogram_map( data, weight, type = c("contiguous", "dorling", "noncontiguous"), fill = NULL, projection = "equal_earth" )
data |
An |
weight |
The column to resize by (unquoted). |
type |
|
fill |
Optional fill column (unquoted); defaults to |
projection |
Projection (an equal-area CRS is recommended). |
A ggplot object.
## Not run: world_data(2020, c(pop = "SP.POP.TOTL"), geometry = "sf") |> cartogram_map(pop, type = "dorling") ## End(Not run)## Not run: world_data(2020, c(pop = "SP.POP.TOTL"), geometry = "sf") |> cartogram_map(pop, type = "dorling") ## End(Not run)
A report on what will and will not match before you trust the map: the
input, its iso3c, whether it matched, and a suggestion (the closest
known country name by string distance) for misses. Surfaced automatically by
join_world().
check_country_match( x, origin = "country.name", custom_match = wdj_overrides(), suggest = TRUE )check_country_match( x, origin = "country.name", custom_match = wdj_overrides(), suggest = TRUE )
x |
A vector of country names or codes. |
origin |
How to read |
custom_match |
Overrides applied before matching (default
|
suggest |
Whether to compute closest-name suggestions for misses
(requires the optional |
A tibble with columns input, iso3c, matched, suggestion.
check_country_match(c("USA", "Cote d'Ivoire", "Yugoslavia", "Wakanda"))check_country_match(c("USA", "Cote d'Ivoire", "Yugoslavia", "Wakanda"))
Forget memoised World Bank fetches, both in-session and (optionally) on disk.
clear_wdi_cache(disk = FALSE)clear_wdi_cache(disk = FALSE)
disk |
Whether to also delete the persistent on-disk cache. |
Invisibly TRUE.
## Not run: clear_wdi_cache() ## End(Not run)## Not run: clear_wdi_cache() ## End(Not run)
A friendly-name to WDI-code lookup so indicator = common_indicators$population
beats memorising "SP.POP.TOTL".
common_indicatorscommon_indicators
A tibble with columns name (friendly name), code (WDI indicator
code) and description.
World Bank indicator catalogue.
Completes a panel so every country has every year, optionally filling missing
values by carry-forward ("locf") or linear interpolation ("linear") so
animations do not flicker on missing years.
complete_years( data, years = NULL, value = NULL, method = c("none", "locf", "linear") )complete_years( data, years = NULL, value = NULL, method = c("none", "locf", "linear") )
data |
A panel with |
years |
The full set of years to complete to. Defaults to the observed min:max. |
value |
Optional value column(s) (character) to fill. If |
method |
|
A completed (and optionally filled) panel tibble.
df <- data.frame(iso3c = "USA", year = c(2000L, 2002L), gdp = c(1, 3)) complete_years(df, 2000:2002, method = "linear")df <- data.frame(iso3c = "USA", year = c(2000L, 2002L), gdp = c(1, 3)) complete_years(df, 2000:2002, method = "linear")
A discoverable wrapper around countrycode::countrycode() exposing the full
set of schemes with first-class shortcuts for the high-value ones: flag
emoji, currency, top-level domain, continent/region and research codes
(Correlates of War, Polity, Gleditsch-Ward, V-Dem, IMF, FAO, FIPS, GAUL).
convert_country( x, to = "iso3c", from = "country.name", custom_match = wdj_overrides(), warn = TRUE )convert_country( x, to = "iso3c", from = "country.name", custom_match = wdj_overrides(), warn = TRUE )
x |
A vector of country names or codes. |
to |
Destination scheme. A shortcut ( |
from |
Origin scheme (default |
custom_match |
Optional overrides (default |
warn |
Whether to warn about unmatched inputs. |
A vector of converted codes.
convert_country(c("Japan", "Brazil"), to = "flag") convert_country("Germany", to = "currency") convert_country(c("USA", "France"), to = "continent")convert_country(c("Japan", "Brazil"), to = "flag") convert_country("Germany", to = "currency") convert_country(c("USA", "France"), to = "continent")
The whole countrycode::codelist reshaped into a tidy, pipeable lookup you
can filter() / join() directly – one row per country.
country_codes(codes = NULL)country_codes(codes = NULL)
codes |
Optional character vector of column names to keep (in addition
to |
A tibble, one row per country.
country_codes() country_codes(c("iso2c", "continent", "currency"))country_codes() country_codes(c("iso2c", "continent", "currency"))
The analysis counterpart to world_data(): no polygons, one tidy row per
country (iso3c, iso2c, country, classifications and the requested
indicators). This is what you actually join() / mutate() / summarise()
/ rank() on; attach geometry only at draw time with attach_geometry().
country_data( year, indicator = NULL, latest = FALSE, panel = FALSE, classify = c("income", "continent", "region"), cache = TRUE, language = "en", parallel = TRUE )country_data( year, indicator = NULL, latest = FALSE, panel = FALSE, classify = c("income", "continent", "region"), cache = TRUE, language = "en", parallel = TRUE )
year |
A single year or a range (with |
indicator |
A named character vector of WDI codes (or |
latest |
Use the most recent non- |
panel |
Return a panel keyed on |
classify |
Which classifications to add. |
cache |
Whether to use the WDI cache. |
language |
WDI language code. |
parallel |
Whether to fetch indicators in parallel. |
A tibble, one row per country (or per country-year for a panel).
country_data(2020, c(co2 = "EN.ATM.CO2E.KT"))country_data(2020, c(co2 = "EN.ATM.CO2E.KT"))
Answers the constant question "is this country in the EU / OECD / G7 / G20 / BRICS / ...?" from a curated, dated membership table (point-in-time membership is genuinely fiddly, so it is shipped and maintained, not guessed). See country_groups_tbl.
country_groups(group = NULL)country_groups(group = NULL)
group |
One or more group names: any of |
A tibble of group, iso3c, country.
country_groups("EU") country_groups(c("G7", "BRICS"))country_groups("EU") country_groups(c("G7", "BRICS"))
A curated, dated membership table for the common country groups.
country_groups_tblcountry_groups_tbl
A tibble with columns group, iso3c, country.
Curated from official membership lists (point-in-time; see the
package NEWS for the reference date).
The generic two-table version of the package's whole reason for being: join
any two data frames that each key on country names or codes, by reconciling
both sides to iso3c first. Tables keyed on "Czech Republic" vs
"Czechia", or "South Korea" vs "Korea, Rep.", just work.
country_join( x, y, by_x, by_y, origin_x = "country.name", origin_y = "country.name", type = c("left", "inner", "full"), suffix = c(".x", ".y") )country_join( x, y, by_x, by_y, origin_x = "country.name", origin_y = "country.name", type = c("left", "inner", "full"), suffix = c(".x", ".y") )
x, y
|
Data frames to join. |
by_x, by_y
|
The country columns in |
origin_x, origin_y
|
How to read each key (countrycode origin schemes). |
type |
Join type: |
suffix |
Suffix for clashing non-key columns (default
|
A tibble joined on a reconciled iso3c key.
a <- data.frame(country = c("Czechia", "South Korea"), gdp = c(1, 2)) b <- data.frame(nation = c("Czech Republic", "Korea, Rep."), pop = c(10, 51)) country_join(a, b, country, nation)a <- data.frame(country = c("Czechia", "South Korea"), gdp = c(1, 2)) b <- data.frame(nation = c("Czech Republic", "Korea, Rep."), pop = c(10, 51)) country_join(a, b, country, nation)
The many-table generalisation of country_join(): reduce-join a list of data
frames that each key on country names or codes, reconciling every one to
iso3c first.
country_join_all( tables, by, origin = "country.name", type = c("full", "left", "inner") )country_join_all( tables, by, origin = "country.name", type = c("full", "left", "inner") )
tables |
A list of data frames. |
by |
A single country-column name present in every table, or a character vector giving the column for each table. |
origin |
countrycode origin scheme(s) for the key column(s) (default
|
type |
Join type: |
A single tibble joined on iso3c (clashing non-key columns get
dplyr's default .x/.y suffixes).
a <- data.frame(country = c("Czechia", "South Korea"), gdp = c(1, 2)) b <- data.frame(country = c("Czech Republic", "Korea, Rep."), pop = c(10, 51)) d <- data.frame(country = c("Czechia", "Korea"), area = c(79, 100)) country_join_all(list(a, b, d), by = "country")a <- data.frame(country = c("Czechia", "South Korea"), gdp = c(1, 2)) b <- data.frame(country = c("Czech Republic", "Korea, Rep."), pop = c(10, 51)) d <- data.frame(country = c("Czechia", "Korea"), area = c(79, 100)) country_join_all(list(a, b, d), by = "country")
One row per country with the facts people constantly need and currently scrape together by hand.
country_metacountry_meta
A tibble with one row per country and columns including iso3c,
iso2c, country, continent, region, un_region, capital,
capital_lat, capital_lon, centroid_lat, centroid_lon, area_km2,
currency, tld, landlocked, flag.
Assembled from countrycode, WDI metadata and Natural Earth geometry.
Facet a choropleth into small multiples (one panel per group or per year) –
the static counterpart to animate_world(), for print and side-by-side
comparison. Builds a world_map() and facets it on facet.
facet_map(data, fill, facet, ncol = NULL, ...)facet_map(data, fill, facet, ncol = NULL, ...)
data |
A map-ready frame (polygon or sf) containing the |
fill |
The fill column (unquoted). |
facet |
The faceting column (unquoted; e.g. |
ncol |
Number of facet columns (passed to |
... |
Passed to |
A faceted ggplot object.
snap <- countryatlas::world_snapshot$countries if (requireNamespace("maps", quietly = TRUE)) { mapdf <- attach_geometry(snap, geometry = "polygon") facet_map(mapdf, gdp_per_capita, continent, style = "quantile") }snap <- countryatlas::world_snapshot$countries if (requireNamespace("maps", quietly = TRUE)) { mapdf <- attach_geometry(snap, geometry = "polygon") facet_map(mapdf, gdp_per_capita, continent, style = "quantile") }
Draws great-circle arcs between country pairs from an origin-destination table (trade, migration, flights, remittances), resolving both endpoints to centroids automatically.
flow_map(data, from, to, weight = NULL, origin = "country.name", n = 50)flow_map(data, from, to, weight = NULL, origin = "country.name", n = 50)
data |
An OD table. |
from, to
|
The origin and destination country columns (unquoted; names
or |
weight |
Optional column controlling arc width/alpha (unquoted). |
origin |
How to read |
n |
Points per arc (smoothness). |
A ggplot object.
od <- data.frame(from = c("China", "Germany"), to = c("United States", "France"), value = c(500, 200)) if (requireNamespace("maps", quietly = TRUE)) { flow_map(od, from, to, value) }od <- data.frame(from = c("China", "Germany"), to = c("United States", "France"), value = c(500, 200)) if (requireNamespace("maps", quietly = TRUE)) { flow_map(od, from, to, value) }
A ggplot2 layer that places labels (names, ISO codes or flag emoji) at
country centroids, with optional ggrepel collision avoidance. Designed for
the polygon backend produced by world_data() / join_world().
geom_country_labels(mapping = NULL, repel = TRUE, flag = FALSE, size = 3, ...)geom_country_labels(mapping = NULL, repel = TRUE, flag = FALSE, size = 3, ...)
mapping |
Aesthetic mapping; defaults to |
repel |
Use |
flag |
If |
size |
Label text size. |
... |
Passed to the underlying text geom. |
A ggplot2 layer.
library(ggplot2) snap <- countryatlas::world_snapshot$countries if (requireNamespace("maps", quietly = TRUE)) { mapdf <- attach_geometry(snap, geometry = "polygon") world_map(mapdf, gdp_per_capita) + geom_country_labels() }library(ggplot2) snap <- countryatlas::world_snapshot$countries if (requireNamespace("maps", quietly = TRUE)) { mapdf <- attach_geometry(snap, geometry = "polygon") world_map(mapdf, gdp_per_capita) + geom_country_labels() }
The world as a globe (orthographic projection) centred on lon/lat – the
honest answer to "the whole world on a rectangle exaggerates the poles". Takes
the same fill / style options as world_map(). The default "sf" backend
gives the cleanest limb; the "polygon" backend draws the globe with
ggplot2::coord_map() and needs only maps + mapproj (no sf).
globe_map( data, fill, lon = 0, lat = 20, backend = c("sf", "polygon"), style = c("continuous", "binned", "quantile", "jenks", "categorical"), palette = NULL, n_bins = 5, borders = TRUE, title = NULL, legend = NULL, na_label = "No data" )globe_map( data, fill, lon = 0, lat = 20, backend = c("sf", "polygon"), style = c("continuous", "binned", "quantile", "jenks", "categorical"), palette = NULL, n_bins = 5, borders = TRUE, title = NULL, legend = NULL, na_label = "No data" )
data |
A map-ready frame: an |
fill |
The fill column (unquoted). |
lon, lat
|
The longitude / latitude the globe is centred on (the face pointing at the viewer). |
backend |
|
style, palette, n_bins, borders, title, legend, na_label
|
As in |
A ggplot object.
## Not run: world_data(2020, geometry = "sf") |> globe_map(gdp_per_capita, lon = 10, lat = 30) # No sf required: globe_map(world_snapshot$countries, continent, backend = "polygon", style = "categorical") ## End(Not run)## Not run: world_data(2020, geometry = "sf") |> globe_map(gdp_per_capita, lon = 10, lat = 30) # No sf required: globe_map(world_snapshot$countries, continent, backend = "polygon", style = "categorical") ## End(Not run)
Adds a growth-rate column to a panel: either the period-over-period change
("yoy") or the compound annual growth rate from the first observed year
("cagr"), computed per country.
growth_rate(data, value, type = c("yoy", "cagr"), suffix = "_growth")growth_rate(data, value, type = c("yoy", "cagr"), suffix = "_growth")
data |
A panel with |
value |
The value column (unquoted). |
type |
|
suffix |
Suffix for the new column (default |
data with a growth-rate column added (a proportion, so 0.03 = 3%).
df <- data.frame(iso3c = "USA", year = 2000:2002, gdp = c(100, 110, 121)) growth_rate(df, gdp)df <- data.frame(iso3c = "USA", year = 2000:2002, gdp = c(100, 110, 121)) growth_rate(df, gdp)
A vectorised membership predicate built on country_groups().
in_group(x, group, origin = "country.name")in_group(x, group, origin = "country.name")
x |
A vector of country names or codes. |
group |
A single group name (see |
origin |
How to read |
A logical vector the same length as x.
in_group(c("France", "United States", "Japan"), "EU")in_group(c("France", "United States", "Japan"), "EU")
Rescales a value column so the chosen base year equals to (100 by default),
per country – the standard way to compare trajectories that start at very
different levels.
index_to(data, value, base_year, to = 100, suffix = "_index")index_to(data, value, base_year, to = 100, suffix = "_index")
data |
A panel with |
value |
The value column (unquoted). |
base_year |
The year set equal to |
to |
The index value the base year maps to (default |
suffix |
Suffix for the new column (default |
data with an index column added.
df <- data.frame(iso3c = "USA", year = 2000:2002, gdp = c(50, 55, 60)) index_to(df, gdp, base_year = 2000)df <- data.frame(iso3c = "USA", year = 2000:2002, gdp = c(50, 55, 60)) index_to(df, gdp, base_year = 2000)
An interactive choropleth with hover and zoom, for dashboards and
R Markdown / Quarto. Engines are all optional Suggests.
interactive_map( data, fill, tooltip = NULL, engine = c("plotly", "ggiraph", "leaflet", "ggsql"), ... )interactive_map( data, fill, tooltip = NULL, engine = c("plotly", "ggiraph", "leaflet", "ggsql"), ... )
data |
A map-ready frame. |
fill |
The fill column (unquoted). |
tooltip |
Optional tooltip column (unquoted). |
engine |
|
... |
Passed to |
An interactive widget.
## Not run: world_data(2020) |> interactive_map(gdp_per_capita) world_data(2020, geometry = "sf") |> interactive_map(gdp_per_capita, engine = "ggsql", transform = "log10") ## End(Not run)## Not run: world_data(2020) |> interactive_map(gdp_per_capita) world_data(2020, geometry = "sf") |> interactive_map(gdp_per_capita, engine = "ggsql", transform = "log10") ## End(Not run)
Auto-detects the country column, standardises it to ISO codes (via
standardize_country()), attaches geometry and returns a plot-ready frame –
the function that fulfils the package's promise for your own data. Pipe the
result straight into world_map().
join_world( data, country_col = NULL, origin = "country.name", geometry = c("polygon", "sf", "none"), scale = "small", region = NULL, projection = "equal_earth", recenter = NULL, warn = TRUE )join_world( data, country_col = NULL, origin = "country.name", geometry = c("polygon", "sf", "none"), scale = "small", region = NULL, projection = "equal_earth", recenter = NULL, warn = TRUE )
data |
A data frame keyed on country names or codes. |
country_col |
The country column (unquoted). If omitted, it is auto-detected. |
origin |
How to read |
geometry |
|
scale |
Natural Earth resolution for the |
region |
Optional region subset (see |
projection, recenter
|
Projection options for the |
warn |
Whether to report unmatched countries (default |
A plot-ready frame: polygon tibble, sf object, or (for
geometry = "none") the standardised table.
rates <- data.frame(country = c("United States", "Brazil", "Kenya"), vaccination_pct = c(0.7, 0.8, 0.6)) if (requireNamespace("maps", quietly = TRUE)) { joined <- join_world(rates, country) }rates <- data.frame(country = c("United States", "Brazil", "Kenya"), vaccination_pct = c(0.7, 0.8, 0.6)) if (requireNamespace("maps", quietly = TRUE)) { joined <- join_world(rates, country) }
Point-in-polygon lookup: given longitude / latitude vectors (or an sf POINT
object), return the iso3c of the country each point falls in – the bridge
for getting point data (events, stations, observations) onto the country
spine so it can be joined, aggregated and mapped like everything else.
locate_country( lon = NULL, lat = NULL, points = NULL, scale = "small", add = "country" )locate_country( lon = NULL, lat = NULL, points = NULL, scale = "small", add = "country" )
lon, lat
|
Numeric vectors of longitude / latitude (recycled together;
ignored if |
points |
Optional |
scale |
Natural Earth resolution for the lookup geometry. |
add |
Extra attributes to return alongside |
A tibble with one row per point: iso3c plus any add columns
(NA for points that fall in no country, e.g. open ocean).
## Not run: locate_country(lon = c(2.35, -74.0), lat = c(48.85, 40.7)) # Paris, NYC ## End(Not run)## Not run: locate_country(lon = c(2.35, -74.0), lat = c(48.85, 40.7)) # Paris, NYC ## End(Not run)
Removes the "is this map just a population map?" footgun by dividing a value
column by population. If no population column is supplied, SP.POP.TOTL is
pulled automatically for the relevant countries and years.
per_capita(data, value, pop = NULL, suffix = "_per_capita", cache = TRUE)per_capita(data, value, pop = NULL, suffix = "_per_capita", cache = TRUE)
data |
A country-level (or panel) data frame with |
value |
The value column to normalise (unquoted). |
pop |
Optional population column (unquoted). If absent, population is fetched from WDI. |
suffix |
Suffix for the new column (default |
cache |
Whether to use the WDI cache when fetching population. |
data with a new per-capita column.
df <- data.frame(iso3c = c("USA", "CHN"), year = 2020L, co2 = c(5e6, 1e7), pop = c(331e6, 1402e6)) per_capita(df, co2, pop)df <- data.frame(iso3c = c("USA", "CHN"), year = 2020L, co2 = c(5e6, 1e7), pop = c(331e6, 1402e6)) per_capita(df, co2, pop)
Adds rank, percentile and z_score for a value column, optionally within
a group (region, year, ...), for "top 10" tables and labelling.
rank_countries(data, value, within = NULL, desc = TRUE)rank_countries(data, value, within = NULL, desc = TRUE)
data |
A data frame. |
value |
The value column to rank (unquoted). |
within |
Optional grouping column(s) (unquoted or character) to rank within. |
desc |
Rank descending (largest = rank 1); default |
data with rank, percentile and z_score columns added.
df <- data.frame(iso3c = c("USA", "CHN", "IND"), gdp = c(21, 17, 3)) rank_countries(df, gdp)df <- data.frame(iso3c = c("USA", "CHN", "IND"), gdp = c(21, 17, 3)) rank_countries(df, gdp)
The "act on it" companion to check_country_match(): replaces unmatched
country names with their closest known country name (by string distance), but
only when the match is confident enough, and reports what it changed. Pipe the
result into standardize_country() / join_world().
repair_country_names( x, threshold = 0.2, origin = "country.name", verbose = TRUE )repair_country_names( x, threshold = 0.2, origin = "country.name", verbose = TRUE )
x |
A vector of country names. |
threshold |
Maximum string distance to accept a repair (0 = identical,
1 = unrelated). Lower is stricter; default |
origin |
countrycode origin scheme (default |
verbose |
Whether to message the substitutions made (default |
A character vector the same length as x, with confident misses
replaced by the closest known country name (others left unchanged). The
applied substitutions are attached as the attribute "repairs".
repair_country_names(c("United States", "Brzil", "Germny"))repair_country_names(c("United States", "Brzil", "Germny"))
Reduce the vertex count of an sf object via the optional rmapshaper
package (falling back to sf::st_simplify()), for fast web/plotting.
simplify_geometry(x, keep = 0.05, ...)simplify_geometry(x, keep = 0.05, ...)
x |
An |
keep |
Proportion of vertices to keep (0-1) for |
... |
Passed to the underlying simplifier. |
A simplified sf object.
## Not run: world_geometry(geometry = "sf") |> simplify_geometry(keep = 0.1) ## End(Not run)## Not run: world_geometry(geometry = "sf") |> simplify_geometry(keep = 0.1) ## End(Not run)
An animated GIF of the world rotating on its axis: a sequence of orthographic
globe_map() frames at evenly spaced central longitudes, assembled into a
looping animation with the optional gifski (preferred) or magick package.
Embeds directly in R Markdown / Quarto / a README.
spin_globe( data, fill, lat = 20, n_frames = 60, fps = 15, backend = c("polygon", "sf"), width = 480, height = 480, file = NULL, ... )spin_globe( data, fill, lat = 20, n_frames = 60, fps = 15, backend = c("polygon", "sf"), width = 480, height = 480, file = NULL, ... )
data |
A map-ready frame (see |
fill |
The fill column (unquoted). |
lat |
The latitude the globe is tilted toward (the viewer's eye line). |
n_frames |
Number of frames in one full 360 degrees rotation. |
fps |
Frames per second of the output animation. |
backend |
|
width, height
|
Pixel dimensions of the animation. |
file |
Optional output path ( |
... |
Passed to |
The path to the written GIF, invisibly.
## Not run: # No sf required: spin_globe(world_snapshot$countries, continent, backend = "polygon", style = "categorical") ## End(Not run)## Not run: # No sf required: spin_globe(world_snapshot$countries, continent, backend = "polygon", style = "categorical") ## End(Not run)
The package's mission, exposed for your data: take a data frame keyed on
messy country names (or codes) and attach standardised ISO codes plus useful
classifications, reconciling spellings via countrycode::countrycode() and
the curated wdj_overrides() table. The result joins cleanly to anything
else keyed on iso3c.
standardize_country( data, country_col, origin = "country.name", add = c("iso3c", "iso2c", "continent", "region"), custom_match = wdj_overrides(), warn = TRUE )standardize_country( data, country_col, origin = "country.name", add = c("iso3c", "iso2c", "continent", "region"), custom_match = wdj_overrides(), warn = TRUE )
data |
A data frame / tibble. |
country_col |
The column holding country names or codes (unquoted, tidy-eval). |
origin |
How to read |
add |
Character vector of attributes to add. Defaults to
|
custom_match |
A named character vector of name -> iso3c overrides;
defaults to |
warn |
Whether to warn about unmatched countries (default |
data with the requested columns added (and existing same-named
columns overwritten).
df <- data.frame(nation = c("U.S.", "S. Korea", "Czechia"), value = 1:3) standardize_country(df, nation)df <- data.frame(nation = c("U.S.", "S. Korea", "Czechia"), value = 1:3) standardize_country(df, nation)
Strips axes, panel grid and background so the map is the focus. Used by all the package's plotting functions and exported for reuse.
theme_world_map(base_size = 12, base_family = "")theme_world_map(base_size = 12, base_family = "")
base_size |
Base font size. |
base_family |
Base font family. |
A ggplot2 theme object.
library(ggplot2) ggplot() + theme_world_map()library(ggplot2) ggplot() + theme_world_map()
A statebins-style equal-area tile grid of the world (one square per country)
so tiny states are actually visible. Uses the bundled world_tiles layout
(and geofacet when available for small multiples).
tile_map(data, fill, label = TRUE)tile_map(data, fill, label = TRUE)
data |
A country-level frame with |
fill |
The fill column (unquoted). |
label |
Whether to draw ISO codes on the tiles (default |
A ggplot object.
tile_map(countryatlas::world_snapshot$countries, gdp_per_capita)tile_map(countryatlas::world_snapshot$countries, gdp_per_capita)
A tidy, pipeable wrapper on WDI::WDIsearch() for discovering indicator
codes.
wdi_search(pattern, field = c("name", "indicator"), cache = NULL)wdi_search(pattern, field = c("name", "indicator"), cache = NULL)
pattern |
A regular expression to search indicator names/codes for. |
field |
Which field to search: |
cache |
Optional cached |
A tibble of matching indicator codes and names.
wdi_search("CO2 emissions")wdi_search("CO2 emissions")
A documented custom_match table for entities that map backends
(ggplot2::map_data() and Natural Earth) get wrong or leave without an ISO
code. Earlier versions of the package deleted these regions; now they are
matched instead, so they stop silently disappearing from maps.
country_overrides() is the preferred name as of the package's rename to
countryatlas; wdj_overrides() is kept as a backward-compatible alias.
wdj_overrides(extra = NULL) country_overrides(extra = NULL)wdj_overrides(extra = NULL) country_overrides(extra = NULL)
extra |
An optional named character vector of additional overrides
(names are country/region names, values are |
The table maps a country/region name (as spelled by the geometry backends) to
an ISO 3166-1 alpha-3 code. Pass the result as the custom_match argument to
standardize_country(), world_data() and friends. Every downstream code
(iso2c, continent, region, flag, ...) is derived from this iso3c, so a
single override is enough.
A named character vector suitable for countrycode(custom_match=).
wdj_overrides() wdj_overrides(c(Somaliland = "SOM")) country_overrides()wdj_overrides() wdj_overrides(c(Somaliland = "SOM")) country_overrides()
The package's headline function, generalised but backward-compatible. Returns
a tibble that already stitches together map geometry, World Bank indicators
and the countrycode crosswalk, keyed on the ISO spine – ready to pipe into
world_map() or ggplot2.
world_data( year, indicator = c(gdp_per_capita = "NY.GDP.PCAP.KD"), geometry = c("polygon", "sf", "none"), scale = c("small", "medium", "large"), region = NULL, classify = c("income", "continent", "region"), projection = "equal_earth", recenter = NULL, latest = FALSE, cache = TRUE, language = "en", parallel = TRUE, overrides = wdj_overrides() )world_data( year, indicator = c(gdp_per_capita = "NY.GDP.PCAP.KD"), geometry = c("polygon", "sf", "none"), scale = c("small", "medium", "large"), region = NULL, classify = c("income", "continent", "region"), projection = "equal_earth", recenter = NULL, latest = FALSE, cache = TRUE, language = "en", parallel = TRUE, overrides = wdj_overrides() )
year |
A single year or a range (e.g. |
indicator |
A named character vector of WDI codes. Names drive column
names, e.g. |
geometry |
|
scale |
Natural Earth resolution for the |
region |
Optional subset: a continent, group name, |
classify |
Which classifications to add (any of |
projection, recenter
|
Projection options for the |
latest |
If |
cache |
Whether to use the memoised / on-disk WDI cache. |
language |
WDI language code (default |
parallel |
Whether to fetch multiple indicators in parallel. |
overrides |
Name -> iso3c overrides for geometry matching (default
|
world_data(2020) keeps its original behaviour (polygon backend, GDP per
capita). Everything else is opt-in: any indicator(s), a span of years (a
panel), an sf backend with real projections, and region subsetting.
A tibble (polygon backend), sf object (sf backend) or country-level
tibble (geometry = "none").
world_data(2020) world_data(2020, indicator = c(life_exp = "SP.DYN.LE00.IN"), geometry = "none")world_data(2020) world_data(2020, indicator = c(life_exp = "SP.DYN.LE00.IN"), geometry = "none")
Sometimes you just want the canvas: country polygons, label-ready centroids, coastlines, internal borders, a graticule or an ocean rectangle – already projected, region-subset and antimeridian-safe. This is the building block the plotting functions sit on, exposed for power users.
world_geometry( what = c("countries", "centroids", "coastline", "borders", "graticule", "ocean"), geometry = c("polygon", "sf"), scale = "small", region = NULL, projection = "equal_earth", recenter = NULL )world_geometry( what = c("countries", "centroids", "coastline", "borders", "graticule", "ocean"), geometry = c("polygon", "sf"), scale = "small", region = NULL, projection = "equal_earth", recenter = NULL )
what |
What to return: |
geometry |
|
scale |
Natural Earth resolution for the |
region |
Optional subset: a continent, a group name, a vector of |
projection |
Projection for the |
recenter |
Optional central meridian for a recentred map (e.g. |
A tibble (polygon backend) or sf object (sf backend).
if (requireNamespace("maps", quietly = TRUE)) { head(world_geometry("countries", geometry = "polygon")) }if (requireNamespace("maps", quietly = TRUE)) { head(world_geometry("countries", geometry = "polygon")) }
Encapsulates the choropleth boilerplate and goes beyond a single style.
Auto-detects the polygon vs sf backend, applies theme_world_map(), and –
for sf – a real projection via ggplot2::coord_sf(). Binned / quantile /
jenks styles are offered because a continuous fill on a skewed indicator
hides almost all the variation; binning is the honest default for
choropleths.
world_map( data, fill, style = c("continuous", "binned", "quantile", "jenks", "categorical"), projection = "equal_earth", palette = NULL, n_bins = 5, borders = TRUE, title = NULL, legend = NULL, na_label = "No data", recenter = NULL )world_map( data, fill, style = c("continuous", "binned", "quantile", "jenks", "categorical"), projection = "equal_earth", palette = NULL, n_bins = 5, borders = TRUE, title = NULL, legend = NULL, na_label = "No data", recenter = NULL )
data |
A map-ready frame from |
fill |
The fill column (unquoted). |
style |
|
projection |
For the |
palette |
Optional palette name passed to the relevant |
n_bins |
Number of bins for binned/quantile/jenks styles. |
borders |
Draw country borders (default |
title, legend
|
Optional plot title and legend title. |
na_label |
Legend label for missing data. |
recenter |
Optional central meridian for the |
A ggplot object.
snap <- countryatlas::world_snapshot$countries if (requireNamespace("maps", quietly = TRUE)) { mapdf <- attach_geometry(snap, geometry = "polygon") world_map(mapdf, gdp_per_capita, style = "quantile") }snap <- countryatlas::world_snapshot$countries if (requireNamespace("maps", quietly = TRUE)) { mapdf <- attach_geometry(snap, geometry = "polygon") world_map(mapdf, gdp_per_capita, style = "quantile") }
Build a ggsql query string that draws a choropleth from
a registered countryatlas source – the same idea as world_map(), but the
map is rendered in the database (DuckDB) and returned as a web-ready
Vega-Lite widget, so the geometry never has to come back into R. Pure string
builder with no dependencies; pair it with as_ggsql_source() +
ggsql::ggsql_execute(), or drop the string into a {ggsql} chunk.
world_query( fill, source = "countryatlas_world", projection = "equal_earth", palette = "viridis", transform = NULL, title = NULL, draw = "spatial" )world_query( fill, source = "countryatlas_world", projection = "equal_earth", palette = "viridis", transform = NULL, title = NULL, draw = "spatial" )
fill |
The fill column (unquoted or a string). |
source |
The table/source name registered with ggsql (default
|
projection |
A projection ggsql's |
palette |
A scale ggsql's |
transform |
Optional scale transform for |
title |
Optional plot title ( |
draw |
The spatial layer (default |
A ggsql_query string (prints as the formatted query).
world_query(gdp_per_capita, projection = "equal_earth", palette = "magma", transform = "log10", title = "GDP per capita")world_query(gdp_per_capita, projection = "equal_earth", palette = "magma", transform = "log10", title = "GDP per capita")
A small, lazy-loaded snapshot of a curated indicator set for one recent year,
as both a country-level tibble and a low-resolution sf object. It lets every
example, test and vignette run offline and deterministically, without the
World Bank API.
world_snapshotworld_snapshot
A list with two elements:
A tibble, one row per country, with iso3c, iso2c,
country, classifications and curated indicators
(gdp_per_capita, population, life_expectancy, co2_per_capita).
A low-resolution sf object with the same per-country columns and
a geometry column (Natural Earth 110m). Present only if sf was
available when the package was built.
The reference year.
World Bank via WDI; geometry from Natural Earth via rnaturalearth.
A statebins-style equal-area tile layout: one square per country, positioned
on a row/col grid derived from country centroids. Used by tile_map().
world_tilesworld_tiles
A tibble with columns iso3c, country, row, col.
Derived from Natural Earth country centroids.