
inedemogR provides tidy access to demographic data from the Spanish
National Statistics Institute (INE), specifically its “fenómenos
demográficos” domain: population, births, and deaths. Data is retrieved
live via the official ineapir API wrapper and
tidied into long/wide data frames, with optional spatial integration via
mapSpain and
sf.
Install the released version from CRAN with:
install.packages("inedemogR")Version 0.2.0 corrects numerical errors in 0.1.0 (the Andreev-Kingkade a0, old-age smoothing, the ESP 2013 weights, abridged tables, the Pollard decomposition, fertility conventions and missing-data handling); see NEWS.md. Results computed with 0.1.0 should be recomputed with 0.2.0 or later.
You can install the development version of inedemogR from GitHub with:
# install.packages("pak")
pak::pak("jrcarob/inedemogR_package")or
# install.packages("devtools")
devtools::install_github("jrcarob/inedemogR_package")library(inedemogR)
# List available indicators and the INE tables they're wired to
list_ine_indicators()
# Fetch population data for municipalities in 2023 (real INE data)
pop_data <- get_ine_demog(indicator = "population_total", year = 2023)
# Fetch births and deaths by province in the same call
vital_stats <- get_ine_demog(
indicator = c("births_total", "deaths_total"),
year = 2023
)
# Fetch the same population data with geometries attached
pop_sf <- get_ine_demog(
indicator = "population_total",
year = 2023,
region = "^Sevilla$",
geometry = TRUE
)Indicators are only available at the geographic level their source
INE table is actually published at: population_total is
municipality-level, births_total/deaths_total
are province-level. Requesting indicators that span different levels in
one call raises an error rather than silently mixing granularities — see
list_ine_indicators().
inedemogR supports two deliberately parallel, complementary workflows — neither subsumes the other, since they operate at different geographic and demographic granularities.
Workflow (a): export and work with files.
download_ine_data() runs the province-level SHMD mortality
pipeline (births, deaths, population, exposure-to-risk, central death
rates, period life tables, per HMD Methods Protocol V6) and writes the
results to a folder as CSV and/or HMD-format .txt files,
for use outside R:
download_ine_data("ine_data")Workflow (b): stay in R. For quick multi-geo-level
choropleths of total counts, use
get_ine_demog()/get_ine_geo()/plot_ine_map()
(see the example above). For age-structured demographic analysis —
dependency ratios, aging index, sex ratio, population pyramids, life
expectancy — use the province-level, age/sex-disaggregated functions
behind download_ine_data() directly:
pop <- get_ine_population()
# Summary indicators (one row per province x year)
age_dependency_ratio(pop$data)
aging_index(pop$data)
sex_ratio(pop$data)
# Charts
plot_population_pyramid(pop$data, year = max(pop$data$year), region = "A Coruna")
# Life expectancy: full pipeline through life tables, then map it,
# bridging this province-level analysis back onto get_ine_geo()'s
# spatial layer
deaths <- get_ine_deaths()
exposure <- compute_exposure(pop$data, deaths$data_provinces)
rates <- compute_death_rates(deaths$data_provinces, exposure$data)
lt <- build_life_tables(rates$mx_1x1)
le <- life_expectancy_summary(lt$fltper, sex = "female")
map_life_expectancy(le, year = max(le$year), sex = "female")Note crude_birth_rate() computes a crude birth
rate (births/population), not a total fertility rate. For a true TFR,
use get_ine_births_by_age() (age-of-mother birth counts)
with
age_specific_fertility_rate()/total_fertility_rate():
births_age <- get_ine_births_by_age()
asfr <- age_specific_fertility_rate(births_age$data, pop$data)
total_fertility_rate(asfr)inedemogR is under active development. System A
(get_ine_demog(), get_ine_geo(),
list_ine_indicators(), plot_ine_map())
implements live retrieval and mapping of municipality/province-level
total counts. Migration indicators are not included in this release.
System B
(get_ine_births()/get_ine_deaths()/get_ine_population(),
compute_exposure(), compute_death_rates(),
build_life_tables(), download_ine_data())
implements a province-level, age/sex-disaggregated SHMD mortality
pipeline, with summary indicators (age_dependency_ratio(),
aging_index(), sex_ratio(),
crude_birth_rate(), life_expectancy_summary())
and charts (plot_population_pyramid(),
plot_demog_trend(), map_life_expectancy())
built on top. A comprehensive tutorial covering every function, the
mortality-pipeline mathematics, and full worked examples is available
via vignette("inedemogR-tutorial"). Cleaning/harmonization
helpers and projections are planned.
The reproducibility/ folder of the GitHub repository (it
is not part of the CRAN package) contains the INE inputs used in the
SoftwareX article, frozen on 5 October 2026 with their provenance, INE’s
published reference series, and the scripts that regenerate every
reported number, table and figure offline. From a clone of the
repository:
Rscript reproducibility/01_validation.R # benchmark vs INE, sensitivity, bootstrap
Rscript reproducibility/02_manuscript_numbers.R # every number in the article
Rscript reproducibility/03_figures.R # the article's figures
Rscript reproducibility/04_rate_benchmark.R # grouped death rates vs INE
Rscript reproducibility/05_fertility_benchmark.R # TFR and mean age at childbearing vs INEAcross 2002-2024, provincial e0 and e65 agree with INE’s published
tables within 0.25 years for every province whose INE table closes at
95+ (see reproducibility/output/validation_summary.md in
the repository), and provincial TFR and mean age at childbearing agree
with INE’s published series within 0.01 in 99% and 98% of
province-years, 1975-2024. Life tables are built from 2002 onwards;
INE’s earlier provincial populations are top-coded at 85+.
Tests: devtools::test() runs the fixed-input suite. The
full pipeline on live INE data runs when the environment variable
INEDEMOGR_LIVE_TESTS=true is set (weekly in the
repository’s continuous integration).
If you use inedemogR in your work, please cite it. Run
citation("inedemogR") for the current entry, or use:
Caro-Barrera, J. R. (2026). inedemogR: Tidy Access to Spanish INE Demographic Data. R package version 0.2.0. https://CRAN.R-project.org/package=inedemogR
@Manual{inedemogR,
title = {inedemogR: Tidy Access to Spanish INE Demographic Data},
author = {J. R. Caro-Barrera},
year = {2026},
note = {R package version 0.2.0},
url = {https://CRAN.R-project.org/package=inedemogR},
}