Constructs female, male, and combined-sex single-year period life tables
(ages 0 to 110+) for every province and year in mx_1x1.
build_life_tables(mx_1x1, kannisto_age = NULL, fit_min = KANNISTO_FIT_MIN)The mx_1x1 element of compute_death_rates() (needs the
mx_*, d_*, and e_* columns).
Optional fixed replacement age Y (an integer in
80-100) overriding the HMD 100-deaths rule; for sensitivity analysis.
First age of the Kannisto fitting window (default 80, as in HMD; the window ends at 99). For sensitivity analysis.
A list:
fltper, mltper, bltper: tibbles with nuts3_code,
province_name, year, age, mx, qx, ax, lx, dx, Lx,
Tx, ex.
qc: tibble with one row per table built (nuts3_code, year,
sex, kannisto_age = Y, passed, issues).
failed: tibble of withheld tables (nuts3_code, province_name,
year, sex, reason).
Follows HMD Methods Protocol V6, Section 7.1:
Observed rates are used below the replacement age Y, the lowest age
from 80 with at most 100 female or 100 male deaths, capped at 95 (the
same Y for both sexes).
From Y upward, rates come from a Kannisto model fitted to deaths and
exposures at ages 80-99 by Poisson maximum likelihood, with both
parameters constrained to be non-negative so smoothed rates cannot fall
with age.
Combined-sex rates at ages Y+ weight the smoothed sex-specific rates by
a smoothed female share of exposure; combined-sex a0 is the
death-weighted average of the sex-specific Andreev-Kingkade values.
Deviations from HMD V6, all forced by the INE inputs: (i) exposure uses an
even Lexis-triangle split because INE deaths are not classified by cohort
(see compute_exposure()); (ii) the Kannisto fit uses ages 80-99 because
INE's single-year detail ends at an open interval 100+, whereas HMD fits to
80-110+; (iii) no birth-by-month exposure correction.
A province-year whose input lacks finite rates and exposures at every
single age 0-100 is not tabulated: its three tables are withheld and the
reason is reported in failed. This covers INE releases whose population
or deaths are top-coded below age 100 (for example, some historical years
for Ceuta and Melilla).
age <- 0:100
e <- 1e5
mx <- 0.0003 * exp(0.07 * age)
mx_1x1 <- tibble::tibble(
nuts3_code = "ES111", province_name = "A Coruna", year = 2023, age = age,
mx_female = mx, mx_male = 1.2 * mx, mx_total = 1.1 * mx,
d_female = mx * e, d_male = 1.2 * mx * e, d_total = 2.2 * mx * e,
e_female = e, e_male = e, e_total = 2 * e
)
lt <- build_life_tables(mx_1x1)
#> All 3 life tables passed validation.
lt$fltper
#> # A tibble: 111 × 12
#> nuts3_code province_name year age mx qx ax lx dx
#> <chr> <chr> <dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 ES111 A Coruna 2023 0 0.0003 0.000300 0.148 100000 30.0
#> 2 ES111 A Coruna 2023 1 0.000322 0.000322 0.5 99970. 32.2
#> 3 ES111 A Coruna 2023 2 0.000345 0.000345 0.5 99938. 34.5
#> 4 ES111 A Coruna 2023 3 0.000370 0.000370 0.5 99903. 37.0
#> 5 ES111 A Coruna 2023 4 0.000397 0.000397 0.5 99866. 39.6
#> 6 ES111 A Coruna 2023 5 0.000426 0.000426 0.5 99827. 42.5
#> 7 ES111 A Coruna 2023 6 0.000457 0.000456 0.5 99784. 45.5
#> 8 ES111 A Coruna 2023 7 0.000490 0.000490 0.5 99739. 48.8
#> 9 ES111 A Coruna 2023 8 0.000525 0.000525 0.5 99690. 52.3
#> 10 ES111 A Coruna 2023 9 0.000563 0.000563 0.5 99638. 56.1
#> # ℹ 101 more rows
#> # ℹ 3 more variables: Lx <dbl>, Tx <dbl>, ex <dbl>