Reads the gdp-population pin and returns population per country and year on
the numeric area_code the rest of the package uses. The pin is keyed by
ISO3 (in a column confusingly also called area_code) and reports population
in thousands; both are converted here, so consumers such as
build_food_supply() and build_n_percapita() get the
year/area_code/population contract they document.
Regional residual aggregates in the pin (RAFR, RASI, REUR, RLAM,
ROCE) are not countries and carry no numeric code. They are dropped and
reported rather than silently discarded, since their omission is what makes
the result a countries-only total rather than a world total.
area_code here is polity_area_code, which is a bucket, not an
identity: several ISO3 codes can share one code, and this function sums
them, so some rows are aggregates of more than one territory. WHEP models the
reporting members of bucket 999 in their own right, so with the real pin and
the default options the only such row is code 206 "Sudan (former)", carrying
Sudan plus South Sudan from 2012 on; it resolves to SUD-1956-2011, the
pre-secession territory its two members together cover. Under
options(whep.unfold_rest_of_world = "none") code 999 folds Syria, North
Macedonia, Palestine, Eswatini, Equatorial Guinea and French Guiana as well.
Every folded row is named in a message.
The pin does not cover every area WHEP models, and that is a bigger gap than
the fold. On the real pin 190 of the 256 area codes the crosswalk resolves
get a population row; the 66 that do not include Bhutan, Comoros, New
Caledonia and the Faroe Islands, all of which the commodity balances do give
food to. build_food_supply() and build_n_percapita() inner-join this
table, so those areas are absent from their per-capita output rather than
wrong in it. Both warn and name them instead of dropping them silently;
options(whep.warn_missing_population = FALSE) silences that warning.
population_source = "pin_wpp_fallback" fills the country-years the pin
does not reach from read_wpp_population(), and only those: the pin wins
wherever both have a value, so turning it on cannot move a denominator that
was already published. On the real inputs it adds 44 areas the pin has no row
for at all — Réunion, Bhutan, Comoros, Western Sahara, New Caledonia, the
French overseas departments and the small island states — and 4,755
country-years inside the pin's own year span. Filled rows are stamped
source_pop = "UN WPP 2024".
It is a gap-filler and not a replacement, because the two sources disagree where they overlap: across 12,309 shared country-years they differ by a median 0.64%, a 95th percentile of 4.4% and a maximum of 81%. That is why the pin keeps every value it has under every composition.
population_source = "pin_wpp_fbs_fallback" then fills what NEITHER of those
reaches from read_fbs_population(), the FAOSTAT Food Balance Sheet
population. That source is keyed on the FAOSTAT area code rather than a
present-day ISO3, so it is the only one that reaches a dissolved reporting
area: it closes area 186 Serbia and Montenegro over 1992-2005 (#862) and area
151 Netherlands Antilles over 1961-2010 (#787), the two largest holes in the
denominator. It is anti-joined like the WPP fill, so it too cannot move a
denominator that was already published.
It is the default (#1133). The sources disagree on the value, not just on
the coverage. For area 186 in 2000 FAOSTAT gives 10,801,000; a UN
WPP 2024 territorial sum for the same ground (SRB + MNE + XKX) gives
10,104,000, 6.5% lower; and the SRB + MNE sum a successor walk can actually
reach today gives 8,311,000, 23% lower, because WPP publishes Kosovo
separately and it carries no WHEP area code (#863). Under the default
territory_overlap = "federation" area 186 keeps the FAOSTAT figure and the
Serbia and Montenegro rows from UN WPP are dropped in those years, so the
federation's denominator covers the same territory, from the same
publisher, as the FAOSTAT food divided by it. Measured on the real inputs,
the default adds 45 areas to the pin's 190 and changes no value the pin
already carries; "pin" reproduces the earlier, pin-only table.
population_source = "pin_fbs_fallback" is FAOSTAT's own population
behind the pin, skipping UN WPP. It reaches the two dissolved areas but
only 12 of the 45 areas the pin lacks (202 areas against 235), because the
Food Balance Sheets do not report Bhutan, Comoros, the French overseas
departments or most small island states. Where both FBS and WPP would fill
the same country-year they agree to a median of about 1e-6.
The UN WPP fill stops at 2023, the last year WPP 2024 publishes as an estimate; 2024-2100 are medium-variant projections and are dropped, with a message, rather than returned as population.
Neither fill can overwrite a key the previous source already has, but an
anti-join on (year, area_code) cannot see two different codes naming
the same ground in the same year, and all three sources produce such pairs:
the pin reports 167 Czechia inside 51 Czechoslovakia for 1850–1992, the
UN WPP fill adds the Soviet, Yugoslav and Belgium-Luxembourg successor states
in the federation's own years, and the FBS fill adds 186 Serbia and
Montenegro beside the 272/273 rows the WPP fill has already added.
territory_overlap decides which row survives; the overlaps are found from
the polities database's successor relation, so the answer follows upstream
rather than a list kept here (#939).
Neither ISO3-keyed source can reach an area whose territory no longer exists,
because both are keyed on a present-day ISO3 code. population_source_reach()
reports which areas that leaves out and whether the polities database's
successor relation could stand in for them. Against UN WPP 2024's
vocabulary, exactly one reporting area outside the Rest-of-World bucket is
unreachable by either route: area 151 Netherlands Antilles, ANT-1961-2010,
which carries commodity-balance food in every year from 1961 to 2010 and for
which upstream publishes no successor at all (#787). Reachable is not the
same as safe to sum — see that function and the note at the top of
R/population_reach.R.
Arguments
- years
Optional integer vector of calendar years to keep.
NULL(default) keeps every year the pin covers.- data
Optional named list of pre-loaded inputs to avoid the pin read:
gdp_population(the raw pin, withYear,area_codeas ISO3,popin thousands),wpp_population(aread_wpp_population()output) andfbs_population(aread_fbs_population()output). Falls back towhep_read_file()when absent.- population_source
"pin_wpp_fbs_fallback"(default), which fills the country-years thegdp-populationpin does not cover from UN WPP and then what neither reaches fromread_fbs_population();"pin", the pin alone;"pin_wpp_fallback", the pin then UN WPP; or"pin_fbs_fallback", which fills fromread_fbs_population()alone and never reads UN WPP.- territory_overlap
Which row survives when two area codes describe overlapping territory in the same year, as a dissolved federation and its successor states do. Overlaps are found from the polities database's
successorrelation, transitively."federation"(default) keeps the federation's row and drops the successor states' rows in the years the federation reports. WHEP's own numerator sits on the federation code in exactly those years — the commodity balances carry area 228 for 1961–1991 and Russia only from 1992, area 51 to 1992 and Czechia only from 1993, area 15 to 1999 and Belgium only from 2000 — so this is the row a per-capita divide can actually use, and the sum over areas is the territory counted once."successors"keeps the successor states and drops the federation. It is the finer grain, and it does not reproduce the federation's own figure: on"pin_wpp_fbs_fallback"the successor sum falls 1.6% short of the USSR at 1961 and runs 2.0% over it at 1991, and falls 14.8% (1961) to 17.5% (1991) short of the Yugoslav SFR — the Kosovo gap of #863. Before 1950 no source has the successors at all, so the federation's population is lost rather than redistributed. It also removes three areas from the table outright, because they exist only in the overlapping years: 51 Czechoslovakia, and — undoing exactly what the FBS fill is for — 186 Serbia and Montenegro (#862) and 151 Netherlands Antilles (#787)."none"composes the sources exactly as before and warns. Any sum over areas then double counts; use it only to reproduce a number published before this argument existed.
The default answers "whose is the USSR's 1961?" the same way
resolve_polity_lineage()does on the spatial side (#1004, #1114): its defaultbasis = "historical_polity"places a 1961 row keyed on area 185 Russia ontoF228-1945-1991, the polity the grid support carries that year, and its alternative"constant_territory"keeps the modern reporter, exactly as"successors"does here. The two are complementary, not competing: that function says which polity's cells a row belongs on and moves no value, while this one says which of two rows for one territory survives. The package therefore has one convention, stated in both places and selectable in both.- example
If
TRUE, return a small fixture instead of reading remote data. Defaults toFALSE.
Value
A tibble with year, area_code, population (persons),
source_pop and method_territory_overlap, one row per area code and
year, sorted by year then area code, plus the polity columns below.
source_pop carries the pin's own
vocabulary ("Original", "Linear interpolation", "First value carried backwards"), joined with " + " when a bucket sums ISO3 codes of
differing provenance, or "UN WPP 2024" for a fallback-filled row. A row
is one country in the common case, but area_code is
an aggregation bucket: rows from 2012 on 206 ("Sudan (former)") are sums
over several territories rather than a single country, as are rows on 999
("Rest of World") when the Rest-of-World fold is restored.
Polity columns
Every area-keyed output carries the polity its area_code resolves to in
that row's year:
polity_area_code: The numeric key rows are AGGREGATED on, for the matrix workflows. It is a bucket, not an identity: usereporting_polity_codeto say which territory a row belongs to.reporting_polity_code: The polity itself, e.g.ESP-1846-1914. It is year-aware, so the samearea_coderesolves to different polities in different years, which is the point of the crosswalk.reporting_polity_name: Its name. It can differ from the area's own name where the area folds into an aggregate.reporting_polity_has_geometry: Whether the polity has a polygon in the WHEP polity database, for callers that need to map or intersect it.FALSEis a documented gap upstream, not an error.
Rows whose area_code resolves to no polity keep the columns with NA
rather than being dropped, so a gap is visible instead of silent.
Rows before the back-cast anchor year resolve to the polity live in that
anchor year rather than to the polity live in the row's own year, because
WHEP's pre-anchor series are back-cast onto the anchor-year territory. See
add_polity_code() for the reasoning. Where that polity is not live in the
row's own year – 41.5% of the pre-1961 (area, year) cells –
add_polity_code() says so as mapping_status == "backcast_anchor", and
polity_coverage_gaps() reports it as gap_kind == "backcast_anchor".
These columns do not say so either way.
A row whose year no mapped period covers is resolved to the NEAREST period of
the same area instead, so reporting_polity_code can name a polity that did
not exist in that row's year – FAOSTAT bucket 206 "Sudan (former)" keeps
reporting after SUD-1956-2011 ends, and its post-2011 rows carry that code.
These columns do not say so: add_polity_code() reports such a row as
mapping_status == "out_of_span", and that column is dropped here so that
adding it does not change the schema of every area-keyed output at once.
polity_coverage_gaps() reports the stand-in rows of a built table, and
options(whep.polity_mapping_status = "flag") (or "status") carries the
signal on the outputs themselves. Both are opt-in; the default is no extra
column.
Examples
read_population(example = TRUE)
#> # A tibble: 5 × 8
#> year area_code polity_area_code reporting_polity_code reporting_polity_name
#> <int> <int> <int> <chr> <chr>
#> 1 2010 41 41 CHN-1950-2025 China (PRC)
#> 2 2010 100 100 IND-1949-2025 India
#> 3 2010 231 231 USA-1959-2025 United States of Ameri…
#> 4 2010 101 101 IDN-2002-2025 Indonesia
#> 5 2010 21 21 BRA-1909-2025 Brazil
#> # ℹ 3 more variables: reporting_polity_has_geometry <lgl>, population <dbl>,
#> # method_territory_overlap <chr>
