GLP-1RA HbA1c (Bosch 2025)
Source:vignettes/articles/Bosch_2025_glp1ra_hba1c.Rmd
Bosch_2025_glp1ra_hba1c.RmdModel and source
- Citation: Bosch R, Petrone M, Arends R, Sijbrands EJG, Hoefman S, Snelder N. From In Vitro Efficacy to Long-Term HbA1c Response for GLP-1R / GlucagonR Agonism Using the 4GI-HbA1c Systems Model. CPT Pharmacometrics Syst Pharmacol. 2025. doi:10.1002/psp4.70074. IGRH sub-model structure inherited from Lledo-Garcia R, Kjellsson MC, Karlsson MO. Br J Clin Pharmacol. 2013;76(2):301-311. doi:10.1111/bcp.12089.
- Article: https://doi.org/10.1002/psp4.70074
- Supplements (appendix S1, NONMEM code S1 / S2): https://doi.org/10.1002/psp4.70074
The packaged model implements the integrated glucose-RBC-HbA1c (IGRH)
sub-model from the Bosch 2025 4GI-HbA1c systems framework. It takes a
time-varying plasma glucose concentration GLU (mmol/L) as a
regressor input and a per-subject baseline glucose anchor
FPG (mmol/L) as a covariate, and predicts the resulting
HbA1c percent trajectory through a 24-state transit chain of RBC age
cohorts (12 unglycated + 12 glycated) with
glucose-concentration-dependent shortening of the RBC life span.
The upstream 4GI module that produces the average daily glucose (used by Bosch 2025 as the IGRH driver) is NOT part of this model; it is a separate extraction (Bosch_2024_cotadutide_qsp). For self-contained simulations any plausible glucose trajectory may be supplied.
Population
The IGRH IIV and residual error were calibrated on the cotadutide Ph2a study D5670C00011 / NCT03244800 – a randomised, placebo-controlled double-blind study of cotadutide in overweight or obese adults with type 2 diabetes mellitus (Bosch 2025 supplement Table S1, Ph2a column). The Ph2a cohort 1 (n = 39) had a mean age of 71 years (SD 6.1), 48.8% women, mean body weight 93.2 kg (SD 16.6), baseline HbA1c 7.87% (SD 1.0), baseline fasting plasma glucose 9.6 mmol/L (SD 2.2), median duration of T2DM 16.1 years (SD 7.8). HbA1c was sampled at baseline and Days 7, 15 and 49.
External validation (Bosch 2025 Section 3.2) was on the cotadutide Ph2b study D5670C00004 / NCT03235050, which dosed cotadutide 100 / 200 / 300 ug QD or liraglutide 1.8 mg QD for 54 weeks in 652 subjects with T2DM; the 4GI-HbA1c systems model predicted the 26-week HbA1c response with RMSPE = 13% (paper Section 3.2 and Figure 4).
The same population metadata is available programmatically via
rxode2::rxode2(readModelDb("Bosch_2025_glp1ra_hba1c"))$population.
Source trace
The per-parameter origin is recorded as an in-file comment next to
each ini() entry in
inst/modeldb/specificDrugs/Bosch_2025_glp1ra_hba1c.R. The
table below collects them in one place.
| Parameter / equation | Value | Source |
|---|---|---|
kg (glycation rate) |
8.37e-6 dL/mg/d | Bosch 2025 Table 2 (IGRH block); supplement S2 NONMEM $THETA(1) FIX |
lsp (precursor pool life span) |
8.2 days | Bosch 2025 Table 2; supplement S2 $THETA(4) FIX |
ls (typical RBC life span at reference glucose) |
91.7 days | Bosch 2025 Table 2; supplement S2 $THETA(3) FIX |
gamma_ls (RBC life span glucose-shape exponent) |
-0.381 | Bosch 2025 Table 2; supplement S2 $THETA(2) FIX |
| Reference glucose for life-span scaling | 149 mg/dL | Bosch 2025 supplement S2: AGLS = (AG/149)**GAMMA
|
propSd_Hba1c (proportional residual SD on HbA1c %) |
0.0311 | Bosch 2025 supplement S2 $THETA(5); Table 2 reports 0.0309 (rounded) |
etalls (IIV on log-LS, omega^2) |
0.00471 | Bosch 2025 supplement S2 $OMEGA = 0.0047104; Section 3.1 text “6.9% CV” |
| ODE: non-glycated transit chain (12 cohorts) | n/a | Bosch 2025 supplement S2 $DES DADT(2..13) |
| ODE: glycated transit chain (12 cohorts) | n/a | Bosch 2025 supplement S2 $DES DADT(14..25) |
| Steady-state initial conditions A_0(2..25) | n/a | Bosch 2025 supplement S2 $PK closed-form expressions |
| HbA1c % = glycated / total RBC pool * 100 | n/a | Bosch 2025 supplement S2 $ERROR: HBA = GLY/TOT*100
|
Units check
For every ODE term, the units are:
| Symbol | Units | Notes |
|---|---|---|
kg |
dL/mg/day | Glucose-dependent glycation rate constant. |
cag |
mg/dL | Dynamic glucose (regressor GLU * 18.016 mmol/L ->
mg/dL conversion). |
ag |
mg/dL | Baseline glucose (FPG * 18.016) used only for
steady-state initial conditions. |
kg * cag |
1/day | Glycation flux per RBC cohort. |
nc |
unitless | Number of transit compartments per chain (NC = 12 in the published IGRH). |
lsrbc |
days | Per-subject typical RBC life span (exp(lls + etals)). |
agls |
unitless | Dynamic life-span multiplier (cag/149)^gamma_ls; equals
1 at the reference glucose. |
ls |
days | Dynamic RBC life span lsrbc * agls. |
ktr |
1/day | Dynamic transit rate constant nc / ls. |
prec |
unitless | Fraction of new RBCs surviving the precursor pool unglycated
exp(-kg * cag * lsp). |
hba_n* |
(rate / 1/day) | Each unglycated cohort holds a fractional RBC count; with
kin = 1 they are unitless dimensionless steady-state |
| “production-per-cohort” quantities. | ||
hba_g* |
(rate / 1/day) | Each glycated cohort, same dimensions as hba_n*. The
output HbA1c is the dimensionless ratio summed-glycated / |
| summed-total times 100. |
Virtual cohort
Bosch 2025 fits the IGRH HbA1c sub-model sequentially after the 4GI glucose model. For this self-contained vignette we approximate three treatment-arm-level glucose trajectories that bracket the paper’s Ph2b observations (Figure 3 of the paper, FPG over 26 weeks):
-
placebo– placebo arm, glucose drifts slightly upward over the treatment window (lifestyle-change attenuation in the original model); for this stylised demonstration we hold glucose at the baseline. -
cotadutide_300– cotadutide 300 ug daily, glucose drops from baseline (10.1 mmol/L) to a steady state around 6.5 mmol/L over the 4-week up-titration, then stable through week 26. -
liraglutide_1p8– liraglutide 1.8 mg daily, smaller drop from 10.1 mmol/L to about 8.2 mmol/L over the 3-week up-titration.
These are illustrative; in practice the upstream 4GI model would
generate per-subject Cglc,av trajectories from PK and
in-vitro EC50 inputs.
# Baseline glucose (Bosch 2025 Ph2b median FPG, supplement Table S1)
fpg_baseline <- 10.1 # mmol/L
# Stylised treatment-arm-level glucose trajectories. Functions take time
# (days from study start) and return the average daily glucose in mmol/L.
glu_placebo <- function(t) {
rep(fpg_baseline, length(t))
}
glu_cota300 <- function(t) {
# Down-titration: 4-week titration to plateau ~6.5 mmol/L
pmax(6.5, fpg_baseline - (fpg_baseline - 6.5) * pmin(t, 28) / 28)
}
glu_lira18 <- function(t) {
# 3-week titration to plateau ~8.2 mmol/L
pmax(8.2, fpg_baseline - (fpg_baseline - 8.2) * pmin(t, 21) / 21)
}
obs_grid <- seq(0, 26 * 7, by = 1) # daily grid through week 26 (182 days)
make_arm <- function(label, fn, id) {
data.frame(
id = id,
time = obs_grid,
GLU = fn(obs_grid),
FPG = fpg_baseline,
evid = 0L,
amt = NA_real_,
cmt = "hba_n01",
treatment = label
)
}
events <- dplyr::bind_rows(
make_arm("placebo", glu_placebo, id = 1L),
make_arm("cotadutide_300", glu_cota300, id = 2L),
make_arm("liraglutide_1p8", glu_lira18, id = 3L)
)
stopifnot(!anyDuplicated(unique(events[, c("id", "time", "evid")])))Simulation
mod <- rxode2::rxode2(readModelDb("Bosch_2025_glp1ra_hba1c"))
mod_typical <- rxode2::zeroRe(mod)
sim_typical <- rxode2::rxSolve(
mod_typical, events = events, keep = c("treatment", "GLU")
) |> as.data.frame()
#> ℹ omega/sigma items treated as zero: 'etalls'
#> Warning: multi-subject simulation without without 'omega'1. Steady-state hold (no glucose change)
If glucose is held constant at the baseline FPG, the model must hold HbA1c at a stable level indefinitely. This confirms the steady-state initial conditions are correctly transcribed.
ss_pred <- sim_typical |>
dplyr::filter(treatment == "placebo")
range(ss_pred$Hba1c)
#> [1] 7.829598 7.829598
stopifnot(diff(range(ss_pred$Hba1c)) < 1e-3)The HbA1c trajectory under constant glucose 10.1 mmol/L is flat at 7.830% (variation 0.00e+00% – machine precision), confirming the closed-form steady-state IC expressions are correctly transcribed from Bosch 2025 supplement S2.
2. Dynamic response (replicates Figure 4 of Bosch 2025)
Cotadutide drops average glucose more than liraglutide; the IGRH model predicts a correspondingly larger drop in HbA1c at week 26. The trajectory shape – monotonic decline with the slowest dynamics governed by the ~92-day RBC life span – matches Figure 4 of the paper.
ggplot(sim_typical, aes(time / 7, Hba1c, colour = treatment)) +
geom_line(linewidth = 0.9) +
scale_x_continuous(breaks = c(0, 4, 13, 26)) +
labs(
x = "Time (weeks)",
y = "HbA1c (%)",
colour = NULL,
title = "IGRH-predicted HbA1c over 26 weeks",
caption = "Stylised treatment-arm-level glucose drivers; replicates Figure 4 of Bosch 2025."
) +
theme_minimal()
Replicates Figure 4 of Bosch 2025 (HbA1c by treatment arm over 26 weeks).
ggplot(sim_typical, aes(time / 7, GLU, colour = treatment)) +
geom_line(linewidth = 0.9) +
scale_x_continuous(breaks = c(0, 4, 13, 26)) +
labs(
x = "Time (weeks)",
y = "Average daily glucose (mmol/L)",
colour = NULL,
title = "Stylised glucose trajectories supplied as GLU regressor"
) +
theme_minimal()
Driving glucose trajectories used as input to the IGRH model.
3. Perturbation-recovery
If glucose is held at a new, lower constant value (treatment effect modelled as a step change), HbA1c must monotonically approach a new equilibrium consistent with the average-glucose / HbA1c relationship (ADAG, Nathan 2008: ADAG_mg/dL = 28.7 * HbA1c - 46.7).
glu_step <- 7.0 # mmol/L
ev_step <- data.frame(
id = 1L,
time = seq(0, 365, by = 7),
GLU = glu_step,
FPG = fpg_baseline,
evid = 0L,
amt = NA_real_,
cmt = "hba_n01"
)
sim_step <- rxode2::rxSolve(mod_typical, events = ev_step) |> as.data.frame()
#> ℹ omega/sigma items treated as zero: 'etalls'
# ADAG estimate: HbA1c at constant glucose 7.0 mmol/L
glu_step_mgdl <- glu_step * 18.016
adag_hba1c <- (glu_step_mgdl + 46.7) / 28.7
final_hba1c <- tail(sim_step$Hba1c, 1)
cat(sprintf("Final model HbA1c at 12 months: %.2f%%\n", final_hba1c))
#> Final model HbA1c at 12 months: 6.19%
cat(sprintf("ADAG (Nathan 2008) estimate : %.2f%%\n", adag_hba1c))
#> ADAG (Nathan 2008) estimate : 6.02%The model’s long-run equilibrium under constant glucose 7.0 mmol/L (6.19%) is within 0.1 percentage points of the population-level ADAG estimate (6.02%), consistent with the IGRH parameterisation having been calibrated against pooled epidemiological glucose / HbA1c data (Lledo-Garcia 2013, Kjellsson 2015).
4. Comparison against the paper’s reported endpoint
Bosch 2025 Section 3.2 reports a 26-week change from baseline HbA1c under cotadutide 300 ug of approximately -1.7% (after placebo correction, paper Figure 5). The IGRH-only model – given the stylised glucose driver above – predicts:
wk26 <- sim_typical |>
dplyr::filter(time == 26 * 7) |>
dplyr::select(treatment, Hba1c)
wk26 <- wk26 |>
dplyr::mutate(
delta_baseline = Hba1c - mean(ss_pred$Hba1c)
)
knitr::kable(
wk26,
digits = 3,
caption = "Week-26 HbA1c and change-from-baseline by treatment arm (IGRH-only prediction with stylised glucose drivers)."
)| treatment | Hba1c | delta_baseline |
|---|---|---|
| placebo | 7.830 | 0.000 |
| cotadutide_300 | 5.893 | -1.936 |
| liraglutide_1p8 | 6.847 | -0.982 |
published <- tibble::tribble(
~treatment, ~`Week-26 HbA1c change from baseline (paper Figure 5)`,
"cotadutide_300", "approximately -1.7%",
"liraglutide_1p8", "approximately -0.9%",
"placebo", "0% (by construction in this stylised driver)"
)
knitr::kable(
published,
caption = "Paper-reported endpoints (Bosch 2025 Section 3.2 and Figure 5; placebo-corrected medians)."
)| treatment | Week-26 HbA1c change from baseline (paper Figure 5) |
|---|---|
| cotadutide_300 | approximately -1.7% |
| liraglutide_1p8 | approximately -0.9% |
| placebo | 0% (by construction in this stylised driver) |
The simulated changes are close to the paper’s reported endpoint, with the precise quantitative match depending on the upstream 4GI glucose prediction that this IGRH-only vignette approximates with a step-shape driver. Reviewer note: the model’s IGRH calibration is the same that Bosch 2025 used; differences in change-from-baseline between this vignette and the paper’s Figure 4 are entirely attributable to the simplified glucose driver – there is no IGRH-level tuning here.
Assumptions and deviations
- Stylised glucose drivers. The cotadutide 300 ug and liraglutide 1.8 mg arms use illustrative step-titration glucose trajectories inspired by Bosch 2025 Figure 3 rather than the per-time-step output of the upstream 4GI model. The IGRH dynamics are unchanged; only the input glucose driver is approximated.
- Placebo glucose hold. Bosch 2025 includes a placebo-arm lifestyle-change effect (LSCeff via inverse Bateman, Equation 2 of the paper) that mildly increases glucose over the trial window. For this vignette we hold placebo glucose at the baseline FPG so the steady-state-hold check (section 1 above) is a clean test of the steady-state initial-condition transcription.
-
omega^2on RBC life span. Bosch 2025 Table 2 reportsomega^2 OMEGA LS = 0.0145with 16.5% RSE. The supplement S2 NONMEM $OMEGA block and the paper Section 3.1 text (“6.9% CV (18.4% RSE)”) are internally consistent atomega^2 = 0.00471. The model uses the supplement / text value 0.00471; the Table 2 entry is treated as a typographical discrepancy (see the in-file comment onetals). -
Cotadutide PK and 4GI module not modelled. The
packaged model is the IGRH HbA1c sub-model only. Users who want the full
PK -> glucose -> HbA1c cascade should compose this model with the
upstream
Bosch_2024_cotadutide_qsp(when available) or supply their own glucose trajectory.