---
title: "Joining your own data"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Joining your own data}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE, comment = "#>", message = FALSE, warning = FALSE,
  fig.width = 7, fig.height = 4, fig.align = "center", dpi = 96
)
library(countryatlas)
library(ggplot2)
library(dplyr)
has_sf <- requireNamespace("sf", quietly = TRUE) &&
  requireNamespace("rnaturalearth", quietly = TRUE) &&
  requireNamespace("rnaturalearthdata", quietly = TRUE)
```

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:

```{r}
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)
```

## One call to a map

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

```{r}
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:

```{r}
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)
```

## 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:

```{r}
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")
```

## Check before you trust

Always inspect what failed to match:

```{r}
check_country_match(my_data$nation)
```

## Historical data: dissolved countries

Historical panels bring a nastier failure mode: dissolved entities. Most are
silently unmatched — but some are silently *mis*matched. 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):

```{r}
check_country_match(c("USSR", "Yugoslavia", "West Germany"))
dissolve_country(c("Czechoslovakia", "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:

```{r}
fixed <- repair_country_names(c("Brzil", "Nehterlands", "United States"),
                              verbose = FALSE)
fixed
```

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

```{r}
country_overrides(c(Somaliland = "SOM"))[c("Kosovo", "Somaliland")]
```

## Custom origins

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

```{r}
df <- data.frame(code = c("US", "KR", "BR"))
standardize_country(df, code, origin = "iso2c", warn = FALSE)
```

## 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:

```{r eval = has_sf}
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`.
