Checks: sex ratio at birth (SRB) implausibly far from the expected value, accounting for sample size; no negative/missing counts; no duplicate province-year rows; continuous year coverage.

validate_births(df)

Arguments

df

Output of the data element of get_ine_births().

Value

list(passed = logical, issues = named list of flagged tibbles).

Details

The SRB check does not use a single fixed band (an earlier version used [1.030, 1.070], which flagged ~60% of all province-years, including 38% of Madrid/Barcelona's — clearly miscalibrated: annual province-level SRB is naturally noisy for small birth counts, and this data's own pooled SRB runs about 1.06, already above that band's upper bound even before any noise). Instead it flags a province-year only if both (a) the observed SRB is statistically implausible given that year's birth count, assuming a true underlying SRB of 1.06 (a two-tailed z-test on the male-birth proportion at z > 4, i.e. roughly a 1-in-16,000 event under the null - deliberately strict, since thousands of province-years are tested at once), and (b) the deviation is also practically meaningful (SRB more than 0.03 from 1.06), so statistically-significant-but-tiny deviations in large provinces aren't flagged just because their sample size makes the test hyper-sensitive. An SRB outside [0.90, 1.25] is additionally always flagged as a sanity floor for gross data errors, but only once total births reach 200: below that, even a large swing (e.g. 23 vs. 17 births) is unremarkable binomial noise, not a data problem, and the z-test above already accounts for the small sample correctly.

Examples

births_df <- tibble::tibble(
  nuts3_code = c("ES611", "ES611", "ES612", "ES612"),
  province_name = c("Almeria", "Almeria", "Cadiz", "Cadiz"),
  year = c(2020, 2021, 2020, 2021),
  female = c(950, 970, 1200, 1210),
  male = c(1000, 1020, 1260, 1270),
  total = female + male
)
validate_births(births_df)
#> All birth validation checks passed.
#> $passed
#> [1] TRUE
#> 
#> $issues
#> list()
#>