The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Joining your own data

The headline use case: I have a frame keyed on messy country names — get it on a map. The package exposes the same matching machinery it uses internally.

Standardise any frame

standardize_country() attaches ISO codes and classifications, reconciling spellings automatically:

my_data <- data.frame(
  nation = c("U.S.", "S. Korea", "Czechia", "Kosovo", "Cote d'Ivoire", "UK"),
  score  = c(10, 8, 6, 4, 7, 9)
)
standardize_country(my_data, nation, warn = FALSE)
#> # A tibble: 6 × 6
#>   nation        score iso3c iso2c continent region               
#>   <chr>         <dbl> <chr> <chr> <chr>     <chr>                
#> 1 U.S.             10 USA   US    Americas  North America        
#> 2 S. Korea          8 KOR   KR    Asia      East Asia & Pacific  
#> 3 Czechia           6 CZE   CZ    Europe    Europe & Central Asia
#> 4 Kosovo            4 XKX   XK    Europe    Europe & Central Asia
#> 5 Cote d'Ivoire     7 CIV   CI    Africa    Sub-Saharan Africa   
#> 6 UK                9 GBR   GB    Europe    Europe & Central Asia

One call to a map

join_world() auto-detects the country column, standardises it and attaches geometry:

my_data |>
  join_world(nation, warn = FALSE) |>
  world_map(score, title = "My data on the ISO spine")

Reconcile two messy tables

country_join() joins two frames that each key on country names, by reconciling both sides to iso3c first:

a <- data.frame(country = c("Czechia", "South Korea", "Russia"), gdp = 1:3)
b <- data.frame(nation  = c("Czech Republic", "Korea, Rep.", "Russian Federation"),
                pop = c(10, 51, 144))
country_join(a, b, country, nation)
#> # A tibble: 3 × 5
#>   country       gdp iso3c nation               pop
#>   <chr>       <int> <chr> <chr>              <dbl>
#> 1 Czechia         1 CZE   Czech Republic        10
#> 2 South Korea     2 KOR   Korea, Rep.           51
#> 3 Russia          3 RUS   Russian Federation   144

Reconcile many tables at once

country_join_all() generalises this to a whole list of frames: every table is reconciled to iso3c first, then reduce-joined — three sources spelled three ways collapse into one honest table:

t1 <- data.frame(country = c("Czechia", "South Korea"), gdp = c(1, 2))
t2 <- data.frame(country = c("Czech Republic", "Korea, Rep."), pop = c(10, 51))
t3 <- data.frame(country = c("Czechia", "Korea"), area = c(79, 100))
country_join_all(list(t1, t2, t3), by = "country")
#> # A tibble: 2 × 7
#>   country.x     gdp iso3c country.y        pop country  area
#>   <chr>       <dbl> <chr> <chr>          <dbl> <chr>   <dbl>
#> 1 Czechia         1 CZE   Czech Republic    10 Czechia    79
#> 2 South Korea     2 KOR   Korea, Rep.       51 Korea     100

Check before you trust

Always inspect what failed to match:

check_country_match(my_data$nation)
#> # A tibble: 6 × 5
#>   input         iso3c matched historical suggestion
#>   <chr>         <chr> <lgl>   <lgl>      <chr>     
#> 1 U.S.          USA   TRUE    FALSE      <NA>      
#> 2 S. Korea      KOR   TRUE    FALSE      <NA>      
#> 3 Czechia       CZE   TRUE    FALSE      <NA>      
#> 4 Kosovo        XKX   TRUE    FALSE      <NA>      
#> 5 Cote d'Ivoire CIV   TRUE    FALSE      <NA>      
#> 6 UK            GBR   TRUE    FALSE      <NA>

Historical data: dissolved countries

Historical panels bring a nastier failure mode: dissolved entities. Most are silently unmatched — but some are silently mismatched. countrycode resolves "USSR" to Russia’s RUS, so Soviet-era totals quietly become Russian totals. The historical column in the report above flags both cases, and dissolve_country() resolves them to successor states via the curated historical_codes crosswalk (one row per successor, dated):

check_country_match(c("USSR", "Yugoslavia", "West Germany"))
#> # A tibble: 3 × 5
#>   input        iso3c matched historical suggestion
#>   <chr>        <chr> <lgl>   <lgl>      <chr>     
#> 1 USSR         RUS   TRUE    TRUE       <NA>      
#> 2 Yugoslavia   <NA>  FALSE   TRUE       Yugoslavia
#> 3 West Germany DEU   TRUE    FALSE      <NA>
dissolve_country(c("Czechoslovakia", "France"))
#> # A tibble: 3 × 5
#>   input          historical     dissolved iso3c country 
#>   <chr>          <chr>              <int> <chr> <chr>   
#> 1 Czechoslovakia Czechoslovakia      1993 CZE   Czechia 
#> 2 Czechoslovakia Czechoslovakia      1993 SVK   Slovakia
#> 3 France         <NA>                  NA FRA   France

"West Germany" is the instructive case: it resolves to DEU and is not flagged — correctly so, because the Federal Republic never dissolved. It absorbed the GDR in 1990 and simply continued, so DEU really is the right answer. The crosswalk is curated rather than a blanket rule that anything old-sounding gets flagged, so only the entity that actually ceased to exist is listed: historical_codes maps East Germany (DDR) to DEU.

Repair what can be repaired

repair_country_names() is the “act on it” companion to that report: it substitutes the closest known country name, but only when the match is confident, and attaches a record of what it changed:

fixed <- repair_country_names(c("Brzil", "Nehterlands", "United States"),
                              verbose = FALSE)
fixed
#> [1] "Brazil"        "Netherlands"   "United States"
#> attr(,"repairs")
#> # A tibble: 2 × 2
#>   from        to         
#>   <chr>       <chr>      
#> 1 Brzil       Brazil     
#> 2 Nehterlands Netherlands

If something legitimately cannot be matched (an entity the backends simply do not know), extend the override table:

country_overrides(c(Somaliland = "SOM"))[c("Kosovo", "Somaliland")]
#>     Kosovo Somaliland 
#>      "XKX"      "SOM"

Custom origins

If your key is already an ISO-2 or World Bank code, tell standardize_country() via origin:

df <- data.frame(code = c("US", "KR", "BR"))
standardize_country(df, code, origin = "iso2c", warn = FALSE)
#> # A tibble: 3 × 5
#>   code  iso3c iso2c continent region                   
#>   <chr> <chr> <chr> <chr>     <chr>                    
#> 1 US    USA   US    Americas  North America            
#> 2 KR    KOR   KR    Asia      East Asia & Pacific      
#> 3 BR    BRA   BR    Americas  Latin America & Caribbean

Point data onto the spine

Not all data comes keyed on names — sometimes all you have is coordinates (events, weather stations, survey sites). locate_country() runs a point-in-polygon lookup and tags each point with the country that contains it, so point data joins the ISO spine like everything else. It needs the optional sf + rnaturalearth packages:

locate_country(lon = c(2.35, -74.0, 139.7), lat = c(48.85, 40.7, 35.7))

Coarse coastlines can place a genuinely-onshore point (a port city, say) just outside its country’s simplified polygon; locate_country() snaps such points to the nearest country within tolerance_km (25 km by default) while leaving open-ocean points NA.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.