Iron Deficiency Anaemia Among Surgical Patients at KNUST Health Centre

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.0     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.2     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.1     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(gtsummary)
library(broom)
library(scales)

Attaching package: 'scales'

The following object is masked from 'package:purrr':

    discard

The following object is masked from 'package:readr':

    col_factor
# mclust is referenced via `::` below (not attached) to avoid mclust::count()
# masking dplyr::count() used elsewhere in this document.
elig_clean <- readRDS("outputs/surgical_cohort_eligible_2025_2026.rds")
bundle     <- readRDS("outputs/ida_study_bundle.rds")

model_df            <- bundle$model_df
eligibility_cascade <- bundle$eligibility_cascade
obj1_prevalence     <- bundle$obj1_prevalence
obj1_n              <- bundle$obj1_n
obj2_summary        <- bundle$obj2_summary
obj2_ci             <- bundle$obj2_ci
obj2_ci_indices     <- bundle$obj2_ci_indices
obj2_comparison     <- bundle$obj2_comparison
lpa_model           <- bundle$lpa_model
lpa_class_summary   <- bundle$lpa_class_summary
n_lpa_complete      <- bundle$n_lpa_complete
n_microcytic        <- bundle$n_microcytic
index_lpa_by_class       <- bundle$index_lpa_by_class
index_lpa_agree_crosstab <- bundle$index_lpa_agree_crosstab
n_index_lpa         <- bundle$n_index_lpa
n_multi_index_ida   <- bundle$n_multi_index_ida
fit_ida             <- bundle$fit_ida
fit_ida2            <- bundle$fit_ida2
fit_ida3            <- bundle$fit_ida3
fit_ida_multi       <- bundle$fit_ida_multi
fit_ida_multi2      <- bundle$fit_ida_multi2
lrt_diagnosis       <- bundle$lrt_diagnosis
lrt_interaction     <- bundle$lrt_interaction
dx_summary          <- bundle$dx_summary

Introduction

Iron deficiency anaemia (IDA) is a common but under-characterized comorbidity among surgical patients, with implications for perioperative risk, transfusion needs, and recovery. Ferritin and other iron studies are not routinely available in this setting, so IDA cannot be confirmed biochemically; this study instead classifies “probable IDA” using the WHO haemoglobin criteria for anaemia combined with red blood cell indices (microcytosis and/or hypochromia) suggestive of an iron-deficient picture.

The study objectives are to:

  1. Determine the prevalence of anaemia among surgical patients on admission, using WHO haemoglobin criteria.
  2. Determine the proportion of anaemic patients with haematological findings suggestive of iron deficiency anaemia, based on red blood cell indices.
  3. Identify risk factors associated with probable iron deficiency anaemia in surgical in-patients.
  4. Describe the distribution of anaemia according to the demographic characteristics of surgical patients and their surgical diagnoses.

Methods

Case identification and triangulation

Surgical cases were identified by triangulating two independent hospital registers covering January 2025 through June 2026: the anaesthesia register and the surgical notes (operation note) register. Cases were matched across registers on folder number and surgery date (within 2 days) to avoid double-counting the same operation, yielding 1,627 unique surgical cases in the case-finding pool.

Laboratory data linkage

Pre- and post-operative full blood count (FBC) results were linked to patient folder numbers. Because linking laboratory results (which carry only patient name) to folder numbers by name-matching alone risks same-surname collisions, every name-based match was cross-validated against the hospital’s laboratory request attendance log, which records folder number, patient name, and request date directly from the source system. Matches without a corroborating request within 5 days were excluded.

Eligibility criteria

The eligible analytic cohort was defined by the following inclusion and exclusion criteria:

  • Inclusion: age 1 year or above; elective or emergency surgical procedure; documented haemoglobin and complete blood count parameters available.
  • Exclusion: age under 1 year; day-case admissions discharged the same day (or no inpatient admission record at all); incomplete pre-operative complete blood count.
eligibility_cascade |>
  gt::gt() |>
  gt::cols_label(step = "Step", n = "N")
Table 1: Eligibility cascade
Step N
Total case-finding pool 1548
Excluded: age < 1 year 2
Excluded: day-case / no admission record 282
Excluded: incomplete pre-op CBC 276
Eligible cohort 1067

This yielded a final eligible cohort of 1,067 cases.

Anaemia and probable IDA classification

Anaemia was defined using WHO haemoglobin thresholds, adjusted for sex and pregnancy status: haemoglobin below 11 g/dL for obstetric (pregnant) cases, below 12 g/dL for non-pregnant women, and below 13 g/dL for men. Among anaemic patients, “probable IDA” was defined as anaemia accompanied by a microcytic (mean corpuscular volume < 80 fL) and/or hypochromic (mean corpuscular haemoglobin < 27 pg, or mean corpuscular haemoglobin concentration < 32 g/dL) red cell pattern.

Table 1: Demographic and clinical characteristics

t1_df <- elig_clean |>
  mutate(
    surgery_type = factor(surgery_type, levels = c("Elective", "Emergency")),
    anaesthesia_type = factor(anaesthesia_type),
    case_type = factor(if_else(is_obstetric, "Obstetric", "Non-obstetric")),
    who_anaemia_grade = case_when(
      is.na(hgb_preop) ~ NA_character_,
      preop_anaemic    ~ "Anaemic",
      TRUE             ~ "Not anaemic"
    )
  ) |>
  select(
    age_years, gender, case_type, surgery_type, anaesthesia_type, ward_name,
    los_days,
    diabetes_mellitus, hypertension, ckd, peptic_ulcer, sickle_cell, asthma_copd,
    any_chronic_comorbidity,
    hgb_preop, who_anaemia_grade, hgb_postop,
    med_antihypertensive, med_antidiabetic, med_antiplatelet_anticoag,
    med_ppi_ulcer, med_iron_supplement
  )

t1_df |>
  tbl_summary(
    label = list(
      age_years ~ "Age (years)",
      gender ~ "Sex",
      case_type ~ "Case type",
      surgery_type ~ "Surgery type",
      anaesthesia_type ~ "Anaesthesia type",
      ward_name ~ "Admission ward",
      los_days ~ "Length of stay (days)",
      diabetes_mellitus ~ "Diabetes mellitus",
      hypertension ~ "Hypertension",
      ckd ~ "Chronic kidney disease",
      peptic_ulcer ~ "Peptic ulcer disease / gastritis",
      sickle_cell ~ "Sickle cell disease",
      asthma_copd ~ "Asthma / COPD",
      any_chronic_comorbidity ~ "Any chronic comorbidity",
      hgb_preop ~ "Pre-op haemoglobin (g/dL)",
      who_anaemia_grade ~ "Pre-op anaemia (WHO threshold)",
      hgb_postop ~ "Post-op haemoglobin (g/dL)",
      med_antihypertensive ~ "On antihypertensive (90d pre-op)",
      med_antidiabetic ~ "On antidiabetic (90d pre-op)",
      med_antiplatelet_anticoag ~ "On antiplatelet/anticoagulant (90d pre-op)",
      med_ppi_ulcer ~ "On PPI/ulcer medication (90d pre-op)",
      med_iron_supplement ~ "On iron supplementation (90d pre-op)"
    ),
    statistic = list(
      all_continuous() ~ "{median} ({p25}, {p75})",
      all_categorical() ~ "{n} ({p}%)"
    ),
    missing_text = "Missing"
  ) |>
  bold_labels() |>
  modify_header(label ~ "**Characteristic**") |>
  modify_caption(str_glue("**Table 1. Demographic and Clinical Characteristics of the Eligible Surgical Cohort (N = {nrow(elig_clean)})**"))
Table 2: Table 1. Demographic and Clinical Characteristics of the Eligible Surgical Cohort (N = 1067)
Characteristic N = 1,0671
Age (years) 31 (25, 36)
Sex
    FEMALE 867 (81%)
    MALE 200 (19%)
Case type
    Non-obstetric 475 (45%)
    Obstetric 592 (55%)
Surgery type
    Elective 430 (43%)
    Emergency 578 (57%)
    Missing 59
Anaesthesia type
    General 80 (39%)
    Local 11 (5.3%)
    Saddle Block 5 (2.4%)
    Sedation 1 (0.5%)
    Spinal 110 (53%)
    Missing 860
Admission ward
    Childrens Medical Ward 14 (1.3%)
    Emergency Ward 1 (<0.1%)
    Females Medical Ward 205 (19%)
    ICU Ward 8 (0.7%)
    Males Medical Ward 142 (13%)
    Maternity Ward 549 (51%)
    OPD Detention Ward 1 (<0.1%)
    OTMC Special Ward 93 (8.7%)
    Recovery Ward 54 (5.1%)
Length of stay (days) 4.00 (3.00, 5.00)
    Missing 4
Diabetes mellitus 66 (6.2%)
Hypertension 180 (17%)
Chronic kidney disease 1 (<0.1%)
Peptic ulcer disease / gastritis 198 (19%)
Sickle cell disease 5 (0.5%)
Asthma / COPD 17 (1.6%)
Any chronic comorbidity 364 (34%)
Pre-op haemoglobin (g/dL) 11.80 (10.70, 12.90)
Pre-op anaemia (WHO threshold)
    Anaemic 412 (39%)
    Not anaemic 655 (61%)
Post-op haemoglobin (g/dL) 10.40 (9.30, 11.30)
    Missing 388
On antihypertensive (90d pre-op) 168 (16%)
On antidiabetic (90d pre-op) 48 (4.5%)
On antiplatelet/anticoagulant (90d pre-op) 31 (2.9%)
On PPI/ulcer medication (90d pre-op) 123 (12%)
On iron supplementation (90d pre-op) 670 (63%)
1 Median (Q1, Q3); n (%)

Objectives 1 and 2: Anaemia and probable IDA prevalence

The prevalence of anaemia on admission, using WHO haemoglobin criteria, was 38.6% (412 of 1067 cases with a pre-operative haemoglobin measurement).

Among the 412 anaemic patients, the following proportions had red cell indices suggestive of iron deficiency, using the pre-specified cutoff-based definitions (95% Wilson confidence intervals):

obj2_ci |>
  mutate(ci = str_glue("{ci_low}\u2013{ci_high}")) |>
  select(definition, n_flagged, n_denom, pct, ci) |>
  gt::gt() |>
  gt::cols_label(
    definition = "Definition", n_flagged = "N flagged", n_denom = "N (denominator)",
    pct = "%", ci = "95% CI"
  )
Table 3: Red cell indices among anaemic patients (cutoff-based definitions)
Definition N flagged N (denominator) % 95% CI
Microcytic 217 412 52.7 47.7–57.6
Hypochromic 186 412 45.1 40.3–50.1
Microcytic AND hypochromic 164 412 39.8 35.1–44.7
Microcytic OR hypochromic (current "probable IDA") 239 412 58.0 53.1–62.8

Overall, 239 of 1067 eligible cases (22.4%) met the operational (“either”) definition of probable IDA.

RBC-count-based discrimination indices

Several published indices combine MCV, MCH, RDW, and RBC count into a single discriminant score, originally developed to distinguish IDA from beta-thalassaemia trait in patients with microcytic anaemia (Mentzer, 1973; Shine & Lal, 1977; Green & King; Jayabose RDW index). All four are dominated by MCV in their construction, so applying them outside a microcytic population is not meaningful: among anaemic patients here who are not microcytic, 100% trivially exceed the “IDA” cutoff for every index, since a normal MCV alone is enough to drive the ratio above threshold regardless of iron status. These indices are therefore reported only among the 217 microcytic anaemic patients, their intended use case:

obj2_ci_indices |>
  mutate(ci = str_glue("{ci_low}\u2013{ci_high}")) |>
  select(definition, n_flagged, n_denom, pct, ci) |>
  gt::gt() |>
  gt::cols_label(
    definition = "Definition", n_flagged = "N flagged", n_denom = "N (denominator)",
    pct = "%", ci = "95% CI"
  )
Table 4: RBC-count-based discrimination indices, among microcytic anaemic patients only
Definition N flagged N (denominator) % 95% CI
Mentzer index > 13 205 217 94.5 90.3–97
Shine & Lal index > 1530 75 217 34.6 28.3–41.3
Green & King index > 65 179 213 84.0 78.3–88.5
RDW index (Jayabose) > 220 186 213 87.3 81.9–91.3

The four indices disagree considerably with each other – from 34.6% (Shine & Lal) to 94.5% (Mentzer) of microcytic patients classified as “IDA-consistent” rather than “thalassaemia-trait-consistent.” This spread is consistent with the published literature, where Shine & Lal is repeatedly reported as the weakest-performing of these indices. Two further caveats limit how much weight these figures should carry here: (1) these formulas were validated as IDA-vs-thalassaemia-trait discriminants, not as stand-alone IDA-vs-normal tests, and this cohort’s tracked haemoglobinopathy comorbidity is sickle cell disease, not thalassaemia, so the applicability of these specific published cutoffs to this population has not been separately verified; and (2) like the microcytic/hypochromic cutoff rules, none of these indices are validated here against ferritin.

Alternative classification: latent profile analysis

The cutoff-based definitions above all combine the same two binary flags (microcytic, hypochromic) with AND/OR logic, chosen a priori rather than estimated from the data. As an alternative, a Gaussian mixture model (latent profile analysis, mclust) was fit jointly on three continuous red cell indices – MCV, MCH, and RDW-CV – among the 408 anaemic patients with complete, valid values for all three (RDW-CV recorded as exactly 0% in 4 patients was treated as missing, since this is not a physiologically plausible value and most likely reflects an instrument error/flag code). The number of latent classes and covariance structure were selected by BIC across 1-4 classes.

The best-fitting model identified 3 latent classes (VVE covariance structure), which read as a severity gradient rather than a binary split:

lpa_means <- as_tibble(t(lpa_model$parameters$mean), rownames = NULL) |>
  mutate(rank = rank(MCV)) |>
  select(rank, MCV, MCH, RDW_CV)

lpa_class_summary |>
  left_join(lpa_means, by = "rank") |>
  mutate(ci = str_glue("{ci_low}\u2013{ci_high}")) |>
  select(label, n, pct, ci, MCV, MCH, RDW_CV) |>
  gt::gt() |>
  gt::fmt_number(columns = c(MCV, MCH, RDW_CV), decimals = 1) |>
  gt::cols_label(
    label = "Latent class", n = "N", pct = "%", ci = "95% CI (bootstrap)",
    MCV = "Mean MCV", MCH = "Mean MCH", RDW_CV = "Mean RDW-CV"
  )
Table 5: Latent profile analysis: class sizes and bootstrap 95% CIs
Latent class N % 95% CI (bootstrap) Mean MCV Mean MCH Mean RDW-CV
LPA: severe iron-deficient pattern 44 10.8 7.8–37.3 72.3 23.8 19.6
LPA: intermediate pattern 157 38.5 9.3–62.5 77.4 26.1 15.2
LPA: normal-appearing pattern 207 50.7 14.6–69.7 82.1 28.8 13.2

The bootstrap intervals are wide, reflecting genuine estimation uncertainty for a 3-class model at this sample size, rather than a computational artifact.

Do the discrimination indices agree with the latent profile classes?

The four RBC-count-based discrimination indices and the latent profile analysis were built from overlapping but not identical information (the indices additionally use RBC count and, for two of them, haemoglobin). Restricting to the 213 microcytic patients with valid data for both analyses, the following table cross-references each index’s “IDA-consistent” call rate, and the proportion with a majority (3 or 4 of 4) of indices agreeing, against the latent class:

index_lpa_by_class |>
  gt::gt() |>
  gt::cols_label(
    label = "Latent class", n = "N",
    pct_mentzer = "Mentzer +", pct_shine_lal = "Shine & Lal +",
    pct_green_king = "Green & King +", pct_rdwi = "RDW index +",
    pct_majority_agree = "\u22653 of 4 agree"
  )
Table 6: Discrimination index positivity rate by latent profile class (microcytic patients only)
Latent class N Mentzer + Shine & Lal + Green & King + RDW index + ≥3 of 4 agree
LPA: severe iron-deficient pattern 42 92.9 9.5 100.0 100.0 92.9
LPA: intermediate pattern 108 92.6 22.2 82.4 83.3 82.4
LPA: normal-appearing pattern 63 100.0 74.6 76.2 85.7 81.0

Three of the four indices, and the majority-agreement rate, increase monotonically with LPA severity as expected – for example 92.9% of the LPA severe class has a majority of indices agreeing, versus 81.0% of the LPA normal-appearing class. Shine & Lal is the striking exception: it inverts, flagging only 9.5% of the severe class as IDA-consistent versus 74.6% of the normal-appearing class. This is explained by its formula (MCV² x MCH / 100, with no RBC or RDW term): when both MCV and MCH are very low together – precisely the LPA severe-class pattern – the product falls below the 1530 cutoff and is misread as “thalassaemia-like,” a known weakness of this index for advanced/combined microcytic-hypochromic anaemia, consistent with its comparatively poor performance noted in the literature above.

The full distribution of how many of the four indices agree, by latent class, is shown for completeness:

index_lpa_agree_crosstab |>
  gt::gt() |>
  gt::cols_label(
    label = "Latent class", agree_0 = "0 agree", agree_1 = "1 agree",
    agree_2 = "2 agree", agree_3 = "3 agree", agree_4 = "4 agree"
  )
Table 7: Number of the four discrimination indices agreeing, by latent profile class
Latent class 0 agree 1 agree 2 agree 3 agree 4 agree
LPA: intermediate pattern 8 10 1 65 24
LPA: normal-appearing pattern 0 4 8 12 39
LPA: severe iron-deficient pattern 0 0 3 35 4

Comparing the two approaches

obj2_comparison |>
  mutate(ci = str_glue("{ci_low}\u2013{ci_high}")) |>
  select(definition, n_flagged, n_denom, pct, ci) |>
  gt::gt() |>
  gt::cols_label(
    definition = "Definition", n_flagged = "N flagged", n_denom = "N (denominator)",
    pct = "%", ci = "95% CI"
  ) |>
  gt::tab_footnote(
    "Denominators differ by definition: microcytic/hypochromic/both/either use all anaemic patients with the needed indicator(s) non-missing; the four RBC-count-based indices (Mentzer through RDW index) are restricted to microcytic anaemic patients only (their intended use case -- see text); LPA classes use the subset with complete, valid MCV/MCH/RDW-CV (RDW-CV = 0 excluded as implausible)."
  )
Table 8: Probable-IDA definitions compared: cutoff-based vs. latent profile analysis
Definition N flagged N (denominator) % 95% CI
Microcytic 217 412 52.7 47.7–57.6
Hypochromic 186 412 45.1 40.3–50.1
Microcytic AND hypochromic 164 412 39.8 35.1–44.7
Microcytic OR hypochromic (current "probable IDA") 239 412 58.0 53.1–62.8
Mentzer index > 13 205 217 94.5 90.3–97
Shine & Lal index > 1530 75 217 34.6 28.3–41.3
Green & King index > 65 179 213 84.0 78.3–88.5
RDW index (Jayabose) > 220 186 213 87.3 81.9–91.3
LPA: severe iron-deficient pattern 44 408 10.8 7.8–37.3
LPA: intermediate pattern 157 408 38.5 9.3–62.5
LPA: normal-appearing pattern 207 408 50.7 14.6–69.7
Denominators differ by definition: microcytic/hypochromic/both/either use all anaemic patients with the needed indicator(s) non-missing; the four RBC-count-based indices (Mentzer through RDW index) are restricted to microcytic anaemic patients only (their intended use case -- see text); LPA classes use the subset with complete, valid MCV/MCH/RDW-CV (RDW-CV = 0 excluded as implausible).

The current operational (“either”) definition flags 58.0% of anaemic patients, noticeably higher than the combined intermediate-plus-severe latent classes (49.3%). Cross-tabulating individual patients confirms why: a substantial share of patients flagged “probable IDA” by the single-indicator OR rule have a joint MCV/MCH/RDW-CV profile that the multivariate model places in the normal-appearing class – i.e., the cutoff rule appears to trade specificity for sensitivity relative to the latent structure in the data. Neither approach is validated against a biochemical gold standard (ferritin), so this comparison should be read as evidence that the choice of “probable IDA” definition materially changes the estimated prevalence, not as a claim that one method is correct.

Objective 4a: Distribution by demographic characteristics

demo_tbl <- model_df |>
  mutate(age_group = cut(age_years, breaks = c(0, 18, 35, 50, 65, 100), right = FALSE,
                          labels = c("<18", "18-34", "35-49", "50-64", "65+"))) |>
  select(probable_ida, age_group, gender, case_type, ward_name) |>
  tbl_summary(by = probable_ida, missing = "no",
              label = list(age_group ~ "Age group", gender ~ "Sex",
                           case_type ~ "Case type", ward_name ~ "Admission ward")) |>
  add_p(test = list(ward_name ~ "chisq.test")) |>
  modify_header(all_stat_cols() ~ "**Probable IDA = {level}**") |>
  modify_caption("**Table 2. Distribution of Probable IDA by Demographic Characteristics**")
The following warnings were returned during `modify_caption()`:
! For variable `ward_name` (`probable_ida`) and "statistic", "p.value", and
  "parameter" statistics: Chi-squared approximation may be incorrect
demo_tbl
Table 9: Table 2. Distribution of Probable IDA by Demographic Characteristics
Characteristic Probable IDA = FALSE1 Probable IDA = TRUE1 p-value2
Age group

<0.001
    <18 18 (2.2%) 19 (7.9%)
    18-34 549 (66%) 143 (60%)
    35-49 207 (25%) 55 (23%)
    50-64 37 (4.5%) 13 (5.4%)
    65+ 17 (2.1%) 9 (3.8%)
Sex

0.2
    FEMALE 666 (80%) 201 (84%)
    MALE 162 (20%) 38 (16%)
Case type

<0.001
    Non-obstetric 345 (42%) 130 (54%)
    Obstetric 483 (58%) 109 (46%)
Admission ward

<0.001
    Childrens Medical Ward 6 (0.7%) 8 (3.3%)
    Emergency Ward 1 (0.1%) 0 (0%)
    Females Medical Ward 135 (16%) 70 (29%)
    ICU Ward 4 (0.5%) 4 (1.7%)
    Males Medical Ward 122 (15%) 20 (8.4%)
    Maternity Ward 449 (54%) 100 (42%)
    OPD Detention Ward 1 (0.1%) 0 (0%)
    OTMC Special Ward 69 (8.3%) 24 (10%)
    Recovery Ward 41 (5.0%) 13 (5.4%)
1 n (%)
2 Pearson’s Chi-squared test

Objective 4b: Distribution by surgical diagnosis

Indications with fewer than 15 cases in the eligible cohort were grouped as “Other” to keep the table readable; all others are shown individually.

dx_summary |>
  gt::gt() |>
  gt::cols_label(
    diagnosis_group = "Surgical diagnosis",
    n = "N",
    pct_anaemic = "% Anaemic",
    pct_probable_ida = "% Probable IDA"
  ) |>
  gt::fmt_number(columns = c(pct_anaemic, pct_probable_ida), decimals = 1)
Table 10: Anaemia and probable IDA prevalence by surgical diagnosis
Surgical diagnosis N % Anaemic % Probable IDA
Other 432 41.0 22.5
2 Previous C/S 101 37.6 22.8
Ectopic Pregnancy 64 78.1 39.1
Previous C/S 60 33.3 21.7
Uterine fibroid 57 61.4 49.1
Fetal distress 51 21.6 11.8
Cephalopelvic Disproportion (CPD) 47 25.5 14.9
Appendicitis 36 22.2 8.3
Fetal macrosomia 31 48.4 22.6
Breech presentation 27 18.5 11.1
Oligohydramnios 25 28.0 24.0
Inguinal hernia 23 13.0 8.7
Pre Eclampsia 21 19.0 14.3
3 Previous C/S 20 35.0 15.0
Hernia 20 25.0 10.0
Acute appendicitis 18 11.1 11.1
Abnormal presentation 17 29.4 23.5
Umbilical hernia 17 47.1 29.4

Ectopic pregnancy and uterine fibroid stand out with the highest anaemia and probable-IDA rates in the cohort, consistent with their underlying pathophysiology (acute haemorrhage and chronic menstrual blood loss, respectively) and motivating their inclusion as a dedicated predictor in the regression models below.

Objective 3: Risk factors for probable IDA

Two logistic regression models were fit for probable IDA: a comorbidities-only model, and a model additionally including surgical diagnosis category (ectopic pregnancy, uterine fibroid, or other). Chronic kidney disease and sickle cell disease were excluded as predictors due to too few events for stable estimation, and stroke/cerebrovascular accident was excluded entirely (zero cases in the eligible cohort).

t_m1 <- tbl_regression(fit_ida, exponentiate = TRUE,
                        label = list(age_years ~ "Age (years)", gender ~ "Sex",
                                     case_type ~ "Case type", diabetes_mellitus ~ "Diabetes mellitus",
                                     hypertension ~ "Hypertension", peptic_ulcer ~ "Peptic ulcer/gastritis",
                                     asthma_copd ~ "Asthma/COPD")) |>
  add_glance_source_note(include = c(nobs, AIC))

t_m2 <- tbl_regression(fit_ida2, exponentiate = TRUE,
                        label = list(age_years ~ "Age (years)", gender ~ "Sex",
                                     case_type ~ "Case type", diabetes_mellitus ~ "Diabetes mellitus",
                                     hypertension ~ "Hypertension", peptic_ulcer ~ "Peptic ulcer/gastritis",
                                     asthma_copd ~ "Asthma/COPD", diagnosis_cat ~ "Diagnosis category")) |>
  add_glance_source_note(include = c(nobs, AIC))

tbl_merge(
  list(t_m1, t_m2),
  tab_spanner = c("**Model 1: Comorbidities only**", "**Model 2: + Diagnosis category**")
) |>
  modify_caption("**Table 3. Logistic Regression of Probable IDA \u2014 Comorbidities-only vs. Comorbidities + Diagnosis Category**")
The number rows in the tables to be merged do not match, which may result in
rows appearing out of order.
ℹ See `tbl_merge()` (`?gtsummary::tbl_merge()`) help file for details. Use
  `quiet=TRUE` to silence message.
Table 11: Table 3. Logistic Regression of Probable IDA — Comorbidities-only vs. Comorbidities + Diagnosis Category
Characteristic
Model 1: Comorbidities only
Model 2: + Diagnosis category
OR 95% CI p-value OR 95% CI p-value
Age (years) 1.00 0.99, 1.01 >0.9 1.00 0.98, 1.01 0.9
Sex





    FEMALE

    MALE 0.48 0.31, 0.73 <0.001 0.66 0.41, 1.06 0.087
Case type





    Non-obstetric

    Obstetric 0.44 0.31, 0.61 <0.001 0.57 0.40, 0.83 0.003
Diabetes mellitus 0.81 0.40, 1.54 0.5 0.84 0.41, 1.60 0.6
Hypertension 1.33 0.88, 2.00 0.2 1.36 0.89, 2.05 0.2
Peptic ulcer/gastritis 1.01 0.69, 1.45 >0.9 1.03 0.70, 1.50 0.9
Asthma/COPD 2.04 0.68, 5.61 0.2 2.15 0.71, 5.89 0.15
Diagnosis category





    Other



    Ectopic pregnancy


1.97 1.10, 3.48 0.021
    Uterine fibroid


2.75 1.53, 4.93 <0.001
Abbreviations: CI = Confidence Interval, OR = Odds Ratio
No. Obs. = 1,067; AIC = 1,113
No. Obs. = 1,067; AIC = 1,123

A likelihood ratio test confirmed that adding diagnosis category significantly improved model fit (χ² = 14.21, df = 2, p = 0.000819).

Interaction check: case type by diagnosis category

Because ectopic pregnancy and uterine fibroid are themselves gynaecological/obstetric diagnoses, an interaction between diagnosis category and case type (obstetric vs. non-obstetric) was tested.

Table 12
lrt_interaction
Analysis of Deviance Table

Model 1: probable_ida ~ age_years + gender + case_type + diabetes_mellitus + 
    hypertension + peptic_ulcer + asthma_copd + diagnosis_cat
Model 2: probable_ida ~ age_years + gender + case_type + diabetes_mellitus + 
    hypertension + peptic_ulcer + asthma_copd + diagnosis_cat * 
    case_type
  Resid. Df Resid. Dev Df Deviance Pr(>Chi)
1      1057     1092.5                     
2      1055     1091.4  2    1.126   0.5695

The interaction term did not improve model fit (χ² = 1.13, df = 2, p = 0.57), and cell sizes for obstetric ectopic pregnancy and obstetric fibroid cases were small. Model 2 (main effects only) is therefore preferred over the interaction model on both parsimony and statistical grounds.

Sensitivity analysis: a more specific outcome definition

The primary outcome (anaemia + microcytic and/or hypochromic) is deliberately sensitive: any single abnormal red cell index is enough to be flagged “probable IDA.” As a sensitivity analysis, the two regression models above were refit against a stricter, more specific outcome – “multi-index probable IDA” – defined as anaemia + microcytic and at least 3 of the 4 RBC-count-based discrimination indices (Mentzer, Shine & Lal, Green & King, RDW index) agreeing on an IDA-consistent pattern. “At least 3 of 4” (a clear majority) is a judgment call made for this sensitivity analysis, not a published consensus threshold. This flags 179 of 1067 eligible cases (16.8%), versus 239 (22.4%) under the primary definition.

t_s1 <- tbl_regression(fit_ida_multi, exponentiate = TRUE,
                        label = list(age_years ~ "Age (years)", gender ~ "Sex",
                                     case_type ~ "Case type", diabetes_mellitus ~ "Diabetes mellitus",
                                     hypertension ~ "Hypertension", peptic_ulcer ~ "Peptic ulcer/gastritis",
                                     asthma_copd ~ "Asthma/COPD")) |>
  add_glance_source_note(include = c(nobs, AIC))

t_s2 <- tbl_regression(fit_ida_multi2, exponentiate = TRUE,
                        label = list(age_years ~ "Age (years)", gender ~ "Sex",
                                     case_type ~ "Case type", diabetes_mellitus ~ "Diabetes mellitus",
                                     hypertension ~ "Hypertension", peptic_ulcer ~ "Peptic ulcer/gastritis",
                                     asthma_copd ~ "Asthma/COPD", diagnosis_cat ~ "Diagnosis category")) |>
  add_glance_source_note(include = c(nobs, AIC))

tbl_merge(
  list(t_s1, t_s2),
  tab_spanner = c("**Model 1: Comorbidities only**", "**Model 2: + Diagnosis category**")
) |>
  modify_caption("**Table 4. Sensitivity Analysis: Logistic Regression of Multi-Index Probable IDA**")
The number rows in the tables to be merged do not match, which may result in
rows appearing out of order.
ℹ See `tbl_merge()` (`?gtsummary::tbl_merge()`) help file for details. Use
  `quiet=TRUE` to silence message.
Table 13: Table 4. Sensitivity Analysis: Logistic Regression of Multi-Index Probable IDA
Characteristic
Model 1: Comorbidities only
Model 2: + Diagnosis category
OR 95% CI p-value OR 95% CI p-value
Age (years) 1.01 0.99, 1.02 0.3 1.01 0.99, 1.02 0.3
Sex





    FEMALE

    MALE 0.34 0.19, 0.57 <0.001 0.46 0.25, 0.83 0.011
Case type





    Non-obstetric

    Obstetric 0.58 0.40, 0.83 0.003 0.76 0.51, 1.14 0.2
Diabetes mellitus 0.56 0.23, 1.19 0.2 0.58 0.24, 1.23 0.2
Hypertension 1.26 0.79, 1.95 0.3 1.29 0.81, 2.01 0.3
Peptic ulcer/gastritis 1.23 0.82, 1.83 0.3 1.28 0.85, 1.91 0.2
Asthma/COPD 2.08 0.64, 5.89 0.2 2.22 0.68, 6.26 0.2
Diagnosis category





    Other



    Ectopic pregnancy


2.33 1.26, 4.25 0.006
    Uterine fibroid


2.15 1.13, 4.01 0.017
Abbreviations: CI = Confidence Interval, OR = Odds Ratio
No. Obs. = 1,063; AIC = 947
No. Obs. = 1,063; AIC = 953

The direction and significance pattern is broadly consistent with the primary analysis: sex and diagnosis category (ectopic pregnancy, uterine fibroid) remain the only significant predictors, and diabetes, hypertension, peptic ulcer disease/gastritis, and asthma/COPD remain non-significant. This agreement across a markedly stricter outcome definition (16.8% vs. 22.4% flagged) is reassuring for the robustness of the Objective 3 conclusions to how “probable IDA” is defined, even though the absolute prevalence estimate itself is not robust to this choice.

Discussion and limitations

  • No direct iron studies. Ferritin and other iron biomarkers were not available, so IDA could not be confirmed biochemically; “probable IDA” is an indirect classification based on haemoglobin and red cell indices alone, and will misclassify some patients (e.g. anaemia of chronic disease with a similar red cell pattern, or early iron deficiency without yet-established microcytosis).
  • Discrimination indices are validated for a different comparison. The Mentzer/Shine & Lal/Green & King/RDW indices, the “3-of-4 agree” sensitivity threshold, and the latent-class labels are all constructed choices for this analysis, not externally validated rules for this population; the underlying indices were developed and validated to distinguish IDA from beta-thalassaemia trait specifically, not sickle cell disease (this cohort’s tracked haemoglobinopathy) or anaemia of chronic disease.
  • Weak comorbidity signal. None of diabetes mellitus, hypertension, peptic ulcer disease/gastritis, or asthma/COPD were significantly associated with probable IDA, and even the best-fitting model explained relatively little of the variance in outcome (McFadden’s pseudo-R² of 0.038), suggesting an important driver of IDA risk in this population is not captured by the available comorbidity and diagnosis variables.
  • Register-dependent field completeness. Surgery type (elective/emergency) is captured only in the anaesthesia register, while anaesthesia technique is captured only in the surgical notes register; a case appearing in only one register will have one of these two fields missing by design, not at random.
  • Partial second year. The case-finding period spans all of 2025 plus January-June 2026 only; year-over-year comparisons should account for this asymmetry rather than treating 2026 as a full year.
  • “On admission” haemoglobin is a proxy. Pre-operative haemoglobin is defined as the closest laboratory result within 30 days before surgery, which for most cases will reflect admission bloods but is not guaranteed to be measured on the day of admission itself.