| Parameter | Value |
|---|---|
| GDM prevalence | 12% |
| High-risk women | 60% |
| OGTT sensitivity | 90% |
| OGTT specificity | 85% |
| Screening cost | ₹250 |
| Treatment cost | ₹8,000 |
| Adverse outcome (if treated) | 10% |
| Adverse outcome (if missed) | 35% |
Universal vs risk-based screening for gestational diabetes in India
RRC-HTA, AIIMS Bhopal | HTAIn, DHR
Gestational diabetes mellitus (GDM) affects 10–14% of pregnancies in India.
Much higher than Western countries.
Undetected GDM increases risks of: - Macrosomia and birth injuries - Neonatal hypoglycaemia - Pre-eclampsia - Future type 2 diabetes in mother
Should India implement universal screening for GDM using a fasting 75g OGTT, or is risk-based screening more cost-effective?
This is a classic diagnostic decision tree problem.
The kind of analysis you might currently do in Excel or TreeAge — but now in R.
| Parameter | Value |
|---|---|
| GDM prevalence | 12% |
| High-risk women | 60% |
| OGTT sensitivity | 90% |
| OGTT specificity | 85% |
| Screening cost | ₹250 |
| Treatment cost | ₹8,000 |
| Adverse outcome (if treated) | 10% |
| Adverse outcome (if missed) | 35% |
All sourced from Indian studies where available.
library(DiagrammeR)
grViz("
digraph gdm_tree {
graph [rankdir=LR, bgcolor='transparent', fontname='Helvetica', nodesep=0.5]
node [fontname='Helvetica', fontsize=10]
D [label='Screening\nStrategy', shape=square, style=filled, fillcolor='#4e79a7', fontcolor='white', width=1.2]
S1 [label='Universal\nScreening', shape=box, style='filled,rounded', fillcolor='#59a14f', fontcolor='white']
S2 [label='Risk-Based\nScreening', shape=box, style='filled,rounded', fillcolor='#f28e2b', fontcolor='white']
S3 [label='No Formal\nScreening', shape=box, style='filled,rounded', fillcolor='#e15759', fontcolor='white']
C1 [label='GDM+\n(12%)', shape=circle, style=filled, fillcolor='#d4e6f1', width=0.8, fontsize=9]
C2 [label='GDM-\n(88%)', shape=circle, style=filled, fillcolor='#d5f5e3', width=0.8, fontsize=9]
TP [label='Test +\nTreat', shape=box, style='filled,rounded', fillcolor='#aed6f1', fontsize=9]
FN [label='Test -\nMissed', shape=box, style='filled,rounded', fillcolor='#f5b7b1', fontsize=9]
D -> S1
D -> S2
D -> S3
S1 -> C1
S1 -> C2
C1 -> TP
C1 -> FN
}
")Every woman gets an OGTT. Those who test positive receive treatment.
Test results in 10,000 women:
# Screening cost: everyone gets OGTT
cost_screening_universal <- n_cohort * cost_ogtt
# Treatment costs: true positives + false positives
cost_treatment_universal <- (true_positive + false_positive) * cost_gdm_treatment
# Adverse outcomes
adverse_outcomes_universal <- (true_positive * p_adverse_gdm_treated) +
(false_negative * p_adverse_gdm_untreated) +
(false_positive * p_adverse_no_gdm) +
(true_negative * p_adverse_no_gdm)
cost_outcomes_universal <- (adverse_outcomes_universal * cost_adverse) +
((n_cohort - adverse_outcomes_universal) * cost_no_adverse)
total_cost_universal <- cost_screening_universal + cost_treatment_universal +
cost_outcomes_universal# QALYs by outcome group
qaly_tp <- true_positive * ((1 - p_adverse_gdm_treated) * utility_gdm_treated +
p_adverse_gdm_treated * utility_adverse)
qaly_fn <- false_negative * ((1 - p_adverse_gdm_untreated) * utility_no_adverse +
p_adverse_gdm_untreated * utility_adverse)
qaly_fp <- false_positive * ((1 - p_adverse_no_gdm) * utility_gdm_treated +
p_adverse_no_gdm * utility_adverse)
qaly_tn <- true_negative * ((1 - p_adverse_no_gdm) * utility_no_adverse +
p_adverse_no_gdm * utility_adverse)
total_qaly_universal <- qaly_tp + qaly_fn + qaly_fp + qaly_tnOnly high-risk women are offered OGTT. Low-risk women are NOT screened → GDM undetected in ~60% of cases.
# High-risk (60% of cohort)
n_high_risk <- n_cohort * prop_high_risk
# Among high-risk: 18% have GDM (higher prevalence)
# Among low-risk: 3% have GDM (lower prevalence)
# Screened (high-risk only)
tp_hr <- n_high_risk * prev_gdm_high_risk * sens_ogtt
fn_hr <- n_high_risk * prev_gdm_high_risk * (1 - sens_ogtt)
fp_hr <- n_high_risk * (1 - prev_gdm_high_risk) * (1 - spec_ogtt)
# NOT screened (low-risk) → all GDM missed
n_gdm_lr <- n_cohort * prop_low_risk * prev_gdm_low_risk # All undetectedGDM detected only through clinical symptoms (~25% detection rate).
No screening cost, but many cases missed.
Result: Lowest upfront cost, but highest adverse outcome rate due to missed cases.
All three strategies produce: - Costs (screening, treatment, outcome management) - QALYs (quality of life impact) - Adverse outcomes (births with complications)
Then we calculate ICERs to compare cost-effectiveness.
Using No Screening as the reference:
# Risk-Based vs No Screening
icer_risk_vs_none <- (total_cost_risk - total_cost_none) /
(total_qaly_risk - total_qaly_none)
# Universal vs No Screening
icer_univ_vs_none <- (total_cost_universal - total_cost_none) /
(total_qaly_universal - total_qaly_none)
# Universal vs Risk-Based
icer_univ_vs_risk <- (total_cost_universal - total_cost_risk) /
(total_qaly_universal - total_qaly_risk)A negative ICER can mean two opposite things:
| ΔQALYs > 0 (better) | ΔQALYs < 0 (worse) | |
|---|---|---|
| ΔCost > 0 | NE: compare to WTP | DOMINATED |
| ΔCost < 0 | DOMINANT | Trade-off |
Always check the signs of ΔCost and ΔQALYs separately!
NMB removes the ICER ambiguity. Positive ΔNMB = adopt.
\[\text{NMB} = \text{WTP} \times \text{QALYs} - \text{Cost}\]
Highest NMB = optimal strategy — works for any number of comparators.
No more pairwise ICER confusion with 3+ strategies.
Universal screening: - Highest cost (everyone screened) - Lowest adverse outcome rate (most cases detected) - BUT some false positives (unnecessary treatment)
Risk-based screening: - Lower cost (fewer screened) - Intermediate outcome rate (misses low-risk cases)
No screening: - Lowest cost - Highest adverse outcome rate (clinical detection only 25%)
In Excel: Changing GDM prevalence requires tracing through multiple cells across sheets.
In R: Change one number at the top and re-run the entire analysis.
This is where R shines for HTA.
A diagnostic decision tree is a reusable template:
Every diagnostic HTA follows this structure — just with different parameters.
The same GDM model rebuilt with the rdecision package:
→ See the Session 3 Bonus page on the workshop website.
R for HTA (Basics) — RRC-HTA, AIIMS Bhopal