Ceftazidime-avibactam (Li 2019)
Source:vignettes/articles/Li_2019_ceftazidime_avibactam.Rmd
Li_2019_ceftazidime_avibactam.RmdModel and source
Li 2019 built two separate population PK models for the two analytes of the fixed-ratio combination product ceftazidime-avibactam: two NONMEM control streams, two analysis data sets (9,155 observations from 1,975 subjects for ceftazidime, 13,735 from 2,249 for avibactam) and two parameter tables. The two are combined only downstream, in the joint PK/PD target attainment analysis. Per the library’s policy of replicating the authors’ model structure, the extraction is therefore two model files sharing this one vignette.
uiCaz <- rxode2::rxode(readModelDb("Li_2019_ceftazidime"))
uiAvi <- rxode2::rxode(readModelDb("Li_2019_avibactam"))Both are linear two-compartment models with first-order elimination from a central compartment following intravenous infusion, parameterised by CL, Vc, Q and Vp, with a full 4x4 OMEGA block. They differ in almost every covariate detail, which is the main thing this vignette exists to keep straight.
Population
tribble(
~Field, ~Ceftazidime, ~Avibactam,
"Subjects", "1,975", "2,249",
"Observations", "9,155", "13,735",
"Healthy / Phase 1", "86 (4.4%)", "345 (15.3%), incl. renal impairment",
"cIAI", "781 (39.5%)", "786 (34.9%)",
"cUTI", "696 (35.2%)", "705 (31.3%)",
"Nosocomial pneumonia", "412 (20.9%)", "413 (18.4%)",
"Estimated CrCL range", "8-488 mL/min", "11-610 mL/min",
"Unbound fraction", "0.85", "0.92"
) |>
knitr::kable(caption = "Analysis populations (Li 2019 Results, 'Analysis populations'; Methods, 'Analysis data and model construction' and 'Exposure-response analysis').")| Field | Ceftazidime | Avibactam |
|---|---|---|
| Subjects | 1,975 | 2,249 |
| Observations | 9,155 | 13,735 |
| Healthy / Phase 1 | 86 (4.4%) | 345 (15.3%), incl. renal impairment |
| cIAI | 781 (39.5%) | 786 (34.9%) |
| cUTI | 696 (35.2%) | 705 (31.3%) |
| Nosocomial pneumonia | 412 (20.9%) | 413 (18.4%) |
| Estimated CrCL range | 8-488 mL/min | 11-610 mL/min |
| Unbound fraction | 0.85 | 0.92 |
Both data sets pool 11 Phase 1 studies, 2 Phase 2 studies (cIAI and cUTI) and 5 Phase 3 trials (RECLAIM 1/2, RECLAIM 3, RECAPTURE 1/2, REPRISE, REPROVE). The avibactam data set is the larger of the two and additionally spans end-stage renal disease, hemodialysis and augmented renal clearance, which is why only the avibactam model carries terms for those states.
Source trace
Every value in both model files, with its source location.
tribble(
~Quantity, ~Analyte, ~Value, ~Source,
"Structural CL, Vc, Q, Vp", "Ceftazidime", "6.95 L/h, 10.5 L, 31.5 L/h, 7.57 L", "Table 1, theta1-theta4",
"Structural CL, Vc, Q, Vp", "Avibactam", "10.2 L/h, 11.1 L, 5.44 L/h, 6.91 L", "Table 2, theta1-theta4",
"CrCL slopes on CL", "Ceftazidime", "0.0103036 (<100), 0.00125182 (>=100), per mL/min", "Table 1 'Slope 1'/'Slope 2'; Data S1 $PK constants SLOPE1 / SLOPE2",
"CrCL hinge on CL", "Avibactam", "power 1.05 (<80), linear slope 0.00279 (>=80)", "Table 2, theta7 / theta8",
"ESRD on CL", "Avibactam", "x 0.0678 (multiplier)", "Table 2, theta5; form from Data S1 'CLESRD = THETA(5)'",
"Hemodialysis CL", "Avibactam", "20.8 L/h absolute", "Table 2, theta6; Data S1 'ELSE CLT1 = THETA(6)'",
"ARC slope scaling", "Avibactam", "x 0.992 on the supra-80 slope", "Table 2, theta13",
"cIAI on CL", "Ceftazidime", "x 1.16", "Table 1, theta5",
"NP on CL", "Ceftazidime", "x 0.999", "Table 1, theta6",
"cIAI (Phase 2) on CL", "Avibactam", "+0.406 proportional", "Table 2, theta10",
"APACHE II > 10 on CL", "Avibactam", "-0.197 proportional", "Table 2, theta15",
"Asian (non-Chinese, non-Japanese) on CL", "Ceftazidime / Avibactam", "-0.161 / -0.0865 proportional", "Table 1 theta7 / Table 2 theta22",
"Chinese on CL", "Ceftazidime", "-0.0855 proportional", "Table 1, theta8",
"cUTI on Vc", "Ceftazidime / Avibactam", "x 1.03 / +0.434 proportional", "Table 1 theta9 / Table 2 theta11",
"cIAI or NP on Vc", "Ceftazidime / Avibactam", "x 1.14 / +0.329 proportional", "Table 1 theta10 / Table 2 theta12",
"cIAI (Phase 2) on Vc", "Avibactam", "+1.92 proportional", "Table 2, theta9",
"Acute pyelonephritis on Vc", "Ceftazidime", "-0.185 proportional", "Table 1, theta11",
"Asian (any level) on Vc", "Ceftazidime", "-0.27 proportional", "Table 1, theta12",
"Body weight on Vc", "Ceftazidime / Avibactam", "(WT/70)^1.01 / (WT/70)^1.08", "Table 1 theta13 / Table 2 theta14",
"Ventilator on PK day on Vc", "Ceftazidime / Avibactam", "+0.297 / +0.175 proportional", "Table 1 theta14 / Table 2 theta28",
"OMEGA block (CL, Vc, Vp, Q)", "Ceftazidime", "0.179 / 1.10 / 1.21 / 6.70 variances + 6 covariances", "Table 1, footnote b 'Reported as variance'",
"OMEGA block (CL, Vc, Vp, Q)", "Avibactam", "0.349 / 1.147 / 1.494 / 6.359 variances + 6 covariances", "Table 2, footnote b 'Reported as variance'",
"Residual, Phase 1", "Ceftazidime", "prop sqrt(0.04) = 0.2; add sqrt(26489) ng/mL = 0.1628 mg/L", "Table 1, footnote b",
"Residual, Phase 2/3", "Ceftazidime", "prop sqrt(0.114) = 0.338; add sqrt(18.4) ng/mL = 0.00429 mg/L", "Table 1, footnote b",
"Residual, Phase 1/2/3", "Avibactam", "prop 0.173 / 0.492 / 0.363; add 44.6 ng/mL = 0.0446 mg/L (Phase 1 only)", "Table 2, theta17-theta20 (SD scale, $SIGMA FIX 1)",
"Unbound fractions", "Ceftazidime / Avibactam", "0.85 / 0.92", "Methods, 'Exposure-response analysis'",
"Joint PK/PD target", "Both", "50% fT > 8 mg/L (CAZ) and 50% fT > 1 mg/L (AVI)", "Methods, 'PK/PD targets'"
) |>
knitr::kable(caption = "Source trace for Li_2019_ceftazidime.R and Li_2019_avibactam.R. 'Data S1' is the supplementary NONMEM control-stream file (CTS-12-151-s001).")| Quantity | Analyte | Value | Source |
|---|---|---|---|
| Structural CL, Vc, Q, Vp | Ceftazidime | 6.95 L/h, 10.5 L, 31.5 L/h, 7.57 L | Table 1, theta1-theta4 |
| Structural CL, Vc, Q, Vp | Avibactam | 10.2 L/h, 11.1 L, 5.44 L/h, 6.91 L | Table 2, theta1-theta4 |
| CrCL slopes on CL | Ceftazidime | 0.0103036 (<100), 0.00125182 (>=100), per mL/min | Table 1 ‘Slope 1’/‘Slope 2’; Data S1 $PK constants SLOPE1 / SLOPE2 |
| CrCL hinge on CL | Avibactam | power 1.05 (<80), linear slope 0.00279 (>=80) | Table 2, theta7 / theta8 |
| ESRD on CL | Avibactam | x 0.0678 (multiplier) | Table 2, theta5; form from Data S1 ‘CLESRD = THETA(5)’ |
| Hemodialysis CL | Avibactam | 20.8 L/h absolute | Table 2, theta6; Data S1 ‘ELSE CLT1 = THETA(6)’ |
| ARC slope scaling | Avibactam | x 0.992 on the supra-80 slope | Table 2, theta13 |
| cIAI on CL | Ceftazidime | x 1.16 | Table 1, theta5 |
| NP on CL | Ceftazidime | x 0.999 | Table 1, theta6 |
| cIAI (Phase 2) on CL | Avibactam | +0.406 proportional | Table 2, theta10 |
| APACHE II > 10 on CL | Avibactam | -0.197 proportional | Table 2, theta15 |
| Asian (non-Chinese, non-Japanese) on CL | Ceftazidime / Avibactam | -0.161 / -0.0865 proportional | Table 1 theta7 / Table 2 theta22 |
| Chinese on CL | Ceftazidime | -0.0855 proportional | Table 1, theta8 |
| cUTI on Vc | Ceftazidime / Avibactam | x 1.03 / +0.434 proportional | Table 1 theta9 / Table 2 theta11 |
| cIAI or NP on Vc | Ceftazidime / Avibactam | x 1.14 / +0.329 proportional | Table 1 theta10 / Table 2 theta12 |
| cIAI (Phase 2) on Vc | Avibactam | +1.92 proportional | Table 2, theta9 |
| Acute pyelonephritis on Vc | Ceftazidime | -0.185 proportional | Table 1, theta11 |
| Asian (any level) on Vc | Ceftazidime | -0.27 proportional | Table 1, theta12 |
| Body weight on Vc | Ceftazidime / Avibactam | (WT/70)^1.01 / (WT/70)^1.08 | Table 1 theta13 / Table 2 theta14 |
| Ventilator on PK day on Vc | Ceftazidime / Avibactam | +0.297 / +0.175 proportional | Table 1 theta14 / Table 2 theta28 |
| OMEGA block (CL, Vc, Vp, Q) | Ceftazidime | 0.179 / 1.10 / 1.21 / 6.70 variances + 6 covariances | Table 1, footnote b ‘Reported as variance’ |
| OMEGA block (CL, Vc, Vp, Q) | Avibactam | 0.349 / 1.147 / 1.494 / 6.359 variances + 6 covariances | Table 2, footnote b ‘Reported as variance’ |
| Residual, Phase 1 | Ceftazidime | prop sqrt(0.04) = 0.2; add sqrt(26489) ng/mL = 0.1628 mg/L | Table 1, footnote b |
| Residual, Phase 2/3 | Ceftazidime | prop sqrt(0.114) = 0.338; add sqrt(18.4) ng/mL = 0.00429 mg/L | Table 1, footnote b |
| Residual, Phase 1/2/3 | Avibactam | prop 0.173 / 0.492 / 0.363; add 44.6 ng/mL = 0.0446 mg/L (Phase 1 only) | Table 2, theta17-theta20 (SD scale, $SIGMA FIX 1) |
| Unbound fractions | Ceftazidime / Avibactam | 0.85 / 0.92 | Methods, ‘Exposure-response analysis’ |
| Joint PK/PD target | Both | 50% fT > 8 mg/L (CAZ) and 50% fT > 1 mg/L (AVI) | Methods, ‘PK/PD targets’ |
Covariate-effect reproduction
The strongest available check is deterministic: solve each model at a
reference covariate setting and at a perturbed one, read back the
cl and vc the model actually computed, and
compare the ratio against the effect size Li 2019 prints. This exercises
model() end to end and has no Monte Carlo component, so it
is asserted tightly.
# Covariate template: a Phase 3 subject with no infection, non-Asian, 70 kg,
# CRCL at each model's own hinge reference, no renal replacement.
baseCov <- function(model) {
data.frame(
CRCL = if (model == "caz") 97.0537 else 80,
WT = 70,
DIS_CIAI = 0, DIS_CUTI = 0, DIS_HABP = 0, DIS_VABP = 0, DIS_AP = 0,
RACE_ASIAN_OTH = 0, RACE_CHINESE = 0, RACE_JAPANESE = 0,
MECH_VENT = 0, APACHE_II_SEV = 0,
RENALIMP_ESRD = 0, RRT_HEMODIAL_STATUS = 0, RENAL_ARC = 0,
STUDY_CIAI_PH2 = 0,
STUDY_CAZAVI_PHASE2 = 0, STUDY_CAZAVI_PHASE3 = 1
)
}
# Solve a single typical subject (no IIV, no residual) and return the model's
# own computed cl and vc.
typicalParams <- function(ui, cov, model) {
cov <- cov[, intersect(names(cov), ui$all.covs), drop = FALSE]
ev <- data.frame(
id = 1L, time = c(0, 1), amt = c(1000, 0), evid = c(1L, 0L),
dur = c(2, 0), cmt = "central"
)
ev <- cbind(ev, cov[rep(1L, 2L), , drop = FALSE])
s <- rxode2::rxSolve(rxode2::zeroRe(ui), ev, returnType = "data.frame")
c(cl = s$cl[1], vc = s$vc[1])
}
perturb <- function(model, ...) {
cv <- baseCov(model)
ch <- list(...)
for (nm in names(ch)) cv[[nm]] <- ch[[nm]]
cv
}
refCaz <- typicalParams(uiCaz, baseCov("caz"), "caz")
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
refAvi <- typicalParams(uiAvi, baseCov("avi"), "avi")
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
covChecks <- tribble(
~Effect, ~Analyte, ~Parameter, ~Observed, ~Expected, ~Source,
"cIAI vs healthy", "Ceftazidime", "CL",
unname(typicalParams(uiCaz, perturb("caz", DIS_CIAI = 1), "caz")["cl"] / refCaz["cl"]),
1.16, "Table 1 theta5",
"NP vs healthy", "Ceftazidime", "CL",
unname(typicalParams(uiCaz, perturb("caz", DIS_HABP = 1), "caz")["cl"] / refCaz["cl"]),
0.999, "Table 1 theta6",
"Asian (non-Chinese) vs non-Asian", "Ceftazidime", "CL",
unname(typicalParams(uiCaz, perturb("caz", RACE_ASIAN_OTH = 1), "caz")["cl"] / refCaz["cl"]),
1 - 0.161, "Table 1 theta7",
"Chinese vs non-Asian", "Ceftazidime", "CL",
unname(typicalParams(uiCaz, perturb("caz", RACE_CHINESE = 1), "caz")["cl"] / refCaz["cl"]),
1 - 0.0855, "Table 1 theta8",
"CrCL 200 vs 100 mL/min", "Ceftazidime", "CL",
unname(typicalParams(uiCaz, perturb("caz", CRCL = 200), "caz")["cl"] /
typicalParams(uiCaz, perturb("caz", CRCL = 100), "caz")["cl"]),
(0.0103036 * 100 + 0.00125182 * 100) / (0.0103036 * 100), "Table 1 Slope 2",
"cUTI vs healthy", "Ceftazidime", "Vc",
unname(typicalParams(uiCaz, perturb("caz", DIS_CUTI = 1), "caz")["vc"] / refCaz["vc"]),
1.03, "Table 1 theta9",
"cIAI vs healthy", "Ceftazidime", "Vc",
unname(typicalParams(uiCaz, perturb("caz", DIS_CIAI = 1), "caz")["vc"] / refCaz["vc"]),
1.14, "Table 1 theta10",
"Acute pyelonephritis within cUTI", "Ceftazidime", "Vc",
unname(typicalParams(uiCaz, perturb("caz", DIS_CUTI = 1, DIS_AP = 1), "caz")["vc"] /
typicalParams(uiCaz, perturb("caz", DIS_CUTI = 1), "caz")["vc"]),
1 - 0.185, "Table 1 theta11",
"Any Asian vs non-Asian", "Ceftazidime", "Vc",
unname(typicalParams(uiCaz, perturb("caz", RACE_JAPANESE = 1), "caz")["vc"] / refCaz["vc"]),
1 - 0.27, "Table 1 theta12 (Results: '27% lower Vc')",
"Ventilator on PK day", "Ceftazidime", "Vc",
unname(typicalParams(uiCaz, perturb("caz", MECH_VENT = 1), "caz")["vc"] / refCaz["vc"]),
1.297, "Table 1 theta14 (Results: '29.7% higher')",
"CrCL 180 vs 80 mL/min", "Avibactam", "CL",
unname(typicalParams(uiAvi, perturb("avi", CRCL = 180), "avi")["cl"] / refAvi["cl"]),
1.279, "Table 2 theta8 (Results: '27.9% for 100 mL/min over 80')",
"APACHE II > 10", "Avibactam", "CL",
unname(typicalParams(uiAvi, perturb("avi", APACHE_II_SEV = 1), "avi")["cl"] / refAvi["cl"]),
1 - 0.197, "Table 2 theta15 (Results: '19.7% decrease')",
"Asian (non-Chinese) vs non-Asian", "Avibactam", "CL",
unname(typicalParams(uiAvi, perturb("avi", RACE_ASIAN_OTH = 1), "avi")["cl"] / refAvi["cl"]),
1 - 0.0865, "Table 2 theta22 (Results: '8.65% lower CL')",
"ESRD off dialysis", "Avibactam", "CL",
unname(typicalParams(uiAvi, perturb("avi", RENALIMP_ESRD = 1), "avi")["cl"] / refAvi["cl"]),
0.0678, "Table 2 theta5, read as a multiplier (see Errata)",
"cUTI vs healthy", "Avibactam", "Vc",
unname(typicalParams(uiAvi, perturb("avi", DIS_CUTI = 1), "avi")["vc"] / refAvi["vc"]),
1.434, "Table 2 theta11 (Results: '43.4% higher')",
"cIAI (Phase 3) vs healthy", "Avibactam", "Vc",
unname(typicalParams(uiAvi, perturb("avi", DIS_CIAI = 1), "avi")["vc"] / refAvi["vc"]),
1.329, "Table 2 theta12 (Results: '32.9% higher')",
"cIAI (Phase 2) vs healthy", "Avibactam", "Vc",
unname(typicalParams(uiAvi, perturb("avi", DIS_CIAI = 1, STUDY_CIAI_PH2 = 1), "avi")["vc"] / refAvi["vc"]),
2.92, "Table 2 theta9 (replaces, not stacks on, theta12)",
"Ventilator on PK day", "Avibactam", "Vc",
unname(typicalParams(uiAvi, perturb("avi", MECH_VENT = 1), "avi")["vc"] / refAvi["vc"]),
1.175, "Table 2 theta28 (Results: '17.5% higher')",
"Body weight 95 vs 70 kg", "Avibactam", "Vc",
unname(typicalParams(uiAvi, perturb("avi", WT = 95), "avi")["vc"] / refAvi["vc"]),
1.39, "Table 2 theta14; Results: '39% higher' at the 90th percentile",
"Body weight 51 vs 70 kg", "Avibactam", "Vc",
unname(typicalParams(uiAvi, perturb("avi", WT = 51), "avi")["vc"] / refAvi["vc"]),
0.71, "Table 2 theta14; Results: '29% lower' at the 10th percentile"
) |>
mutate(`% diff` = 100 * (Observed - Expected) / Expected)
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
#> Warning: No sigma parameters in the model
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalq'
covChecks |>
mutate(across(c(Observed, Expected, `% diff`), \(x) round(x, 4))) |>
knitr::kable(caption = "Model-computed covariate effects against the values Li 2019 prints. Every row is deterministic.")| Effect | Analyte | Parameter | Observed | Expected | Source | % diff |
|---|---|---|---|---|---|---|
| cIAI vs healthy | Ceftazidime | CL | 1.1600 | 1.1600 | Table 1 theta5 | 0.0000 |
| NP vs healthy | Ceftazidime | CL | 0.9990 | 0.9990 | Table 1 theta6 | 0.0000 |
| Asian (non-Chinese) vs non-Asian | Ceftazidime | CL | 0.8390 | 0.8390 | Table 1 theta7 | 0.0000 |
| Chinese vs non-Asian | Ceftazidime | CL | 0.9145 | 0.9145 | Table 1 theta8 | 0.0000 |
| CrCL 200 vs 100 mL/min | Ceftazidime | CL | 1.1215 | 1.1215 | Table 1 Slope 2 | 0.0000 |
| cUTI vs healthy | Ceftazidime | Vc | 1.0300 | 1.0300 | Table 1 theta9 | 0.0000 |
| cIAI vs healthy | Ceftazidime | Vc | 1.1400 | 1.1400 | Table 1 theta10 | 0.0000 |
| Acute pyelonephritis within cUTI | Ceftazidime | Vc | 0.8150 | 0.8150 | Table 1 theta11 | 0.0000 |
| Any Asian vs non-Asian | Ceftazidime | Vc | 0.7300 | 0.7300 | Table 1 theta12 (Results: ‘27% lower Vc’) | 0.0000 |
| Ventilator on PK day | Ceftazidime | Vc | 1.2970 | 1.2970 | Table 1 theta14 (Results: ‘29.7% higher’) | 0.0000 |
| CrCL 180 vs 80 mL/min | Avibactam | CL | 1.2790 | 1.2790 | Table 2 theta8 (Results: ‘27.9% for 100 mL/min over 80’) | 0.0000 |
| APACHE II > 10 | Avibactam | CL | 0.8030 | 0.8030 | Table 2 theta15 (Results: ‘19.7% decrease’) | 0.0000 |
| Asian (non-Chinese) vs non-Asian | Avibactam | CL | 0.9135 | 0.9135 | Table 2 theta22 (Results: ‘8.65% lower CL’) | 0.0000 |
| ESRD off dialysis | Avibactam | CL | 0.0678 | 0.0678 | Table 2 theta5, read as a multiplier (see Errata) | 0.0000 |
| cUTI vs healthy | Avibactam | Vc | 1.4340 | 1.4340 | Table 2 theta11 (Results: ‘43.4% higher’) | 0.0000 |
| cIAI (Phase 3) vs healthy | Avibactam | Vc | 1.3290 | 1.3290 | Table 2 theta12 (Results: ‘32.9% higher’) | 0.0000 |
| cIAI (Phase 2) vs healthy | Avibactam | Vc | 2.9200 | 2.9200 | Table 2 theta9 (replaces, not stacks on, theta12) | 0.0000 |
| Ventilator on PK day | Avibactam | Vc | 1.1750 | 1.1750 | Table 2 theta28 (Results: ‘17.5% higher’) | 0.0000 |
| Body weight 95 vs 70 kg | Avibactam | Vc | 1.3907 | 1.3900 | Table 2 theta14; Results: ‘39% higher’ at the 90th percentile | 0.0509 |
| Body weight 51 vs 70 kg | Avibactam | Vc | 0.7103 | 0.7100 | Table 2 theta14; Results: ‘29% lower’ at the 10th percentile | 0.0487 |
# Every effect must reproduce the published coefficient. The 1% tolerance
# absorbs only the rounding in the Results prose (e.g. '39% higher' for
# (95/70)^1.08 = 1.3907); the ini() values themselves are exact.
stopifnot(all(abs(covChecks$`% diff`) < 1))Every covariate effect in both models reproduces the published coefficient to within the rounding of the paper’s own prose. Note the two models disagree about which covariates survive selection – ceftazidime keeps a Chinese clearance effect and an acute-pyelonephritis volume effect that avibactam does not, and avibactam keeps an APACHE II clearance effect and ESRD / dialysis / ARC terms that ceftazidime does not. That asymmetry is real and is reproduced faithfully rather than harmonised.
Virtual cohort
The Phase 3 cohort is reconstructed from Li 2019 Table 3, which gives subject counts for every renal-function band and race group. Each subject is assigned the label-recommended regimen for their creatinine clearance, exactly as Table 3’s footnote c describes.
# set.seed() seeds R's RNG, not rxode2's; rxode2 streams are partitioned per
# solver thread, so a CI runner draws a different cohort than a workstation.
# Every assertion below is written to hold for any cohort the model produces.
set.seed(20190211)
rxode2::rxSetSeed(20190211)
N_ARM <- 200L # per indication; the package caps vignette cohorts at 200
# Day 3 CrCL bands and counts, Li 2019 Table 3 (bottom block).
crclBands <- tribble(
~lo, ~hi, ~n,
8, 15, 4,
15, 30, 20,
30, 50, 128,
50, 80, 418,
80, 150, 955,
150, 180, 123,
180, 610, 116
)
drawCrcl <- function(n) {
b <- sample(seq_len(nrow(crclBands)), n, replace = TRUE, prob = crclBands$n)
runif(n, crclBands$lo[b], crclBands$hi[b])
}
# Race distribution, Li 2019 Table 3 'Race' block: White/other 1209,
# Asian non-Chinese 248, Chinese/Taiwanese 262, Japanese 45.
drawRace <- function(n) {
sample(c("White/other", "Asian", "Chinese", "Japanese"), n,
replace = TRUE, prob = c(1209, 248, 262, 45)
)
}
# Label-recommended regimen by CrCL (Li 2019 Table 3 footnote c and Table 4).
regimen <- function(crcl) {
data.frame(
amtCaz = ifelse(crcl <= 30, 750, ifelse(crcl <= 50, 1000, 2000)),
amtAvi = ifelse(crcl <= 30, 187.5, ifelse(crcl <= 50, 250, 500)),
tau = ifelse(crcl <= 15, 24, ifelse(crcl <= 30, 12, 8))
)
}
makeArm <- function(indication, idOffset) {
crcl <- drawCrcl(N_ARM)
race <- drawRace(N_ARM)
# 138 of 413 NP subjects had VAP (Table 3).
vap <- if (indication == "NP") rbinom(N_ARM, 1L, 138 / 413) else rep(0L, N_ARM)
# APACHE II > 10 in 438 of the 1,115 subjects for whom it was collected
# (cIAI and NP only; missing for every cUTI subject and scored as the
# reference level).
apache <- if (indication == "cUTI") rep(0L, N_ARM) else rbinom(N_ARM, 1L, 438 / 1115)
cbind(
data.frame(
id = idOffset + seq_len(N_ARM),
indication = indication,
CRCL = crcl,
WT = pmin(pmax(rlnorm(N_ARM, log(70), 0.23), 40), 150),
DIS_CIAI = as.integer(indication == "cIAI"),
DIS_CUTI = as.integer(indication == "cUTI"),
DIS_VABP = as.integer(vap),
DIS_HABP = as.integer(indication == "NP" & vap == 0L),
DIS_AP = 0L,
RACE_ASIAN_OTH = as.integer(race == "Asian"),
RACE_CHINESE = as.integer(race == "Chinese"),
RACE_JAPANESE = as.integer(race == "Japanese"),
# NPv is 'a ventilator in the room on the PK sampling day'. Only the VAP
# subjects are flagged here; see Assumptions and deviations.
MECH_VENT = as.integer(vap),
APACHE_II_SEV = as.integer(apache),
RENALIMP_ESRD = 0L, RRT_HEMODIAL_STATUS = 0L, RENAL_ARC = 0L,
STUDY_CIAI_PH2 = 0L,
STUDY_CAZAVI_PHASE2 = 0L, STUDY_CAZAVI_PHASE3 = 1L
),
regimen(crcl)
)
}
cohort <- bind_rows(
makeArm("cIAI", 0L),
makeArm("cUTI", N_ARM),
makeArm("NP", 2L * N_ARM)
)
cohort |>
group_by(indication) |>
summarise(
n = n(),
`Median CrCL (mL/min)` = round(median(CRCL), 1),
`Median WT (kg)` = round(median(WT), 1),
`Asian (any), %` = round(100 * mean(RACE_ASIAN_OTH + RACE_CHINESE + RACE_JAPANESE), 1),
`Ventilated, %` = round(100 * mean(MECH_VENT), 1),
`2000-500 mg q8h, %` = round(100 * mean(amtCaz == 2000), 1),
.groups = "drop"
) |>
dplyr::rename(Indication = indication) |>
knitr::kable(caption = "Reconstructed Phase 3 cohort, 200 subjects per indication.")| Indication | n | Median CrCL (mL/min) | Median WT (kg) | Asian (any), % | Ventilated, % | 2000-500 mg q8h, % |
|---|---|---|---|---|---|---|
| NP | 200 | 101.4 | 68.8 | 30.0 | 27 | 89.5 |
| cIAI | 200 | 105.8 | 69.7 | 30.0 | 0 | 93.0 |
| cUTI | 200 | 105.6 | 71.8 | 34.5 | 0 | 87.0 |
Simulation
Steady state is imposed with ss = 1 on the first dose
rather than integrated with a long dose train, then the remaining doses
of a 24-hour window are given explicitly so that AUC over
[0, 24] is the paper’s AUCss,0-24 directly.
Infusions are 2 hours.
TINF <- 2
GRID <- 0.1
makeEvents <- function(cohort, amtCol) {
covCols <- setdiff(
names(cohort),
c("id", "indication", "amtCaz", "amtAvi", "tau")
)
rows <- lapply(seq_len(nrow(cohort)), function(i) {
tau <- cohort$tau[i]
dt <- seq(0, 24 - tau, by = tau)
ot <- seq(0, 24, by = GRID)
dose <- data.frame(
time = dt, amt = cohort[[amtCol]][i], evid = 1L, dur = TINF,
# ss = 1 on the first dose only; the later doses of the window are
# ordinary records layered on top of the steady state it establishes.
ss = c(1L, rep(0L, length(dt) - 1L)), ii = tau
)
obs <- data.frame(time = ot, amt = 0, evid = 0L, dur = 0, ss = 0L, ii = 0)
ev <- rbind(dose, obs)
ev$id <- cohort$id[i]
ev$cmt <- "central"
cbind(ev, cohort[rep(i, nrow(ev)), covCols, drop = FALSE])
})
do.call(rbind, rows)
}
evCaz <- makeEvents(cohort, "amtCaz")
evAvi <- makeEvents(cohort, "amtAvi")
# Cc is the individual prediction. Li 2019's PTA simulations deliberately
# "excluded residual error", so the residual model is switched off with
# sigma = NA and only between-subject variability is retained.
simCaz <- rxode2::rxSolve(uiCaz, evCaz, sigma = NA, returnType = "data.frame")
simAvi <- rxode2::rxSolve(uiAvi, evAvi, sigma = NA, returnType = "data.frame")
sim <- bind_rows(
simCaz |> transmute(id = as.integer(as.character(id)), time, Cc, drug = "Ceftazidime"),
simAvi |> transmute(id = as.integer(as.character(id)), time, Cc, drug = "Avibactam")
) |>
left_join(cohort |> select(id, indication, tau), by = "id")
stopifnot(nrow(sim) > 0, all(is.finite(sim$Cc)))Steady-state profiles by indication
sim |>
group_by(drug, indication, time) |>
summarise(
med = median(Cc), lo = quantile(Cc, 0.1), hi = quantile(Cc, 0.9),
.groups = "drop"
) |>
ggplot(aes(time, med)) +
geom_ribbon(aes(ymin = lo, ymax = hi), alpha = 0.2, fill = "steelblue") +
geom_line(colour = "steelblue") +
facet_grid(drug ~ indication, scales = "free_y") +
scale_y_log10() +
labs(
x = "Time within the steady-state 24-hour window (h)",
y = "Total plasma concentration (mg/L)"
) +
theme_bw()
Median with 10th-90th percentile band, the same summary statistics Li 2019 uses for the prediction-corrected visual predictive checks in Figures 1 (ceftazidime) and 2 (avibactam). The shape reproduces those figures: a 2-hour infusion peak followed by a biphasic decline, with the spread widening markedly at trough because the OMEGA block gives Q a variance of 6.7 (ceftazidime) and 6.4 (avibactam).
PKNCA validation
Steady-state non-compartmental analysis over the full 24-hour window,
which is the interval Li 2019 reports exposures on (Cmax,ss
and AUCss,0-24).
simNca <- sim |>
filter(!is.na(Cc)) |>
transmute(id, time, Cc, drug, indication)
doseNca <- bind_rows(
evCaz |> filter(evid == 1) |> transmute(id, time, amt, drug = "Ceftazidime"),
evAvi |> filter(evid == 1) |> transmute(id, time, amt, drug = "Avibactam")
) |>
left_join(cohort |> select(id, indication), by = "id")
concObj <- PKNCA::PKNCAconc(simNca, Cc ~ time | drug + indication + id,
concu = "mg/L", timeu = "h"
)
doseObj <- PKNCA::PKNCAdose(doseNca, amt ~ time | drug + indication + id,
doseu = "mg"
)
intervals <- data.frame(
start = 0, end = 24,
cmax = TRUE, tmax = TRUE, cmin = TRUE, auclast = TRUE
)
ncaRes <- PKNCA::pk.nca(PKNCA::PKNCAdata(concObj, doseObj, intervals = intervals))
ncaWide <- as.data.frame(ncaRes$result) |>
filter(PPTESTCD %in% c("cmax", "tmax", "cmin", "auclast")) |>
select(drug, indication, id, PPTESTCD, PPORRES)
ncaSummary <- ncaWide |>
group_by(drug, indication, PPTESTCD) |>
summarise(
Median = median(PPORRES, na.rm = TRUE),
P05 = quantile(PPORRES, 0.05, na.rm = TRUE),
P95 = quantile(PPORRES, 0.95, na.rm = TRUE),
.groups = "drop"
) |>
mutate(Parameter = nlmixr2lib::ncaParamLabel(PPTESTCD)) |>
select(Analyte = drug, Indication = indication, Parameter, Median, P05, P95)
stopifnot(nrow(ncaSummary) > 0)
ncaSummary |>
mutate(across(c(Median, P05, P95), \(x) signif(x, 3))) |>
knitr::kable(caption = "Simulated steady-state NCA over 0-24 h, by analyte and indication.")| Analyte | Indication | Parameter | Median | P05 | P95 |
|---|---|---|---|---|---|
| Avibactam | NP | AUClast | 159.00 | 58.700 | 431.00 |
| Avibactam | NP | Cmax | 14.60 | 5.290 | 40.90 |
| Avibactam | NP | Cmin | 1.71 | 0.319 | 8.27 |
| Avibactam | NP | Tmax | 2.00 | 2.000 | 18.00 |
| Avibactam | cIAI | AUClast | 154.00 | 46.000 | 443.00 |
| Avibactam | cIAI | Cmax | 14.40 | 5.080 | 36.20 |
| Avibactam | cIAI | Cmin | 1.41 | 0.249 | 12.30 |
| Avibactam | cIAI | Tmax | 2.00 | 2.000 | 18.00 |
| Avibactam | cUTI | AUClast | 135.00 | 48.500 | 355.00 |
| Avibactam | cUTI | Cmax | 12.40 | 3.980 | 28.50 |
| Avibactam | cUTI | Cmin | 1.50 | 0.300 | 7.16 |
| Avibactam | cUTI | Tmax | 2.00 | 2.000 | 18.00 |
| Ceftazidime | NP | AUClast | 982.00 | 474.000 | 2200.00 |
| Ceftazidime | NP | Cmax | 75.90 | 37.800 | 158.00 |
| Ceftazidime | NP | Cmin | 16.50 | 4.170 | 60.40 |
| Ceftazidime | NP | Tmax | 12.00 | 2.000 | 18.00 |
| Ceftazidime | cIAI | AUClast | 796.00 | 377.000 | 1940.00 |
| Ceftazidime | cIAI | Cmax | 69.00 | 35.100 | 142.00 |
| Ceftazidime | cIAI | Cmin | 10.00 | 2.300 | 50.90 |
| Ceftazidime | cIAI | Tmax | 2.00 | 2.000 | 18.00 |
| Ceftazidime | cUTI | AUClast | 920.00 | 461.000 | 2090.00 |
| Ceftazidime | cUTI | Cmax | 76.20 | 38.100 | 152.00 |
| Ceftazidime | cUTI | Cmin | 13.80 | 3.230 | 58.10 |
| Ceftazidime | cUTI | Tmax | 10.00 | 2.000 | 18.00 |
Comparison against the published exposures
Li 2019 Table 3 reports geometric-mean Cmax,ss and
AUCss,0-24 for the actual Phase 3 patients of each
indication. Because the reference statistic is a geometric mean, the
simulated side is pre-aggregated the same way rather than letting
ncaComparisonTable() pool by its default median.
geomean <- function(x) exp(mean(log(x[x > 0]), na.rm = TRUE))
simGeo <- ncaWide |>
filter(PPTESTCD %in% c("cmax", "auclast")) |>
group_by(indication, PPTESTCD, drug) |>
summarise(PPORRES = geomean(PPORRES), .groups = "drop") |>
mutate(group = paste(drug, indication, sep = " / ")) |>
select(group, PPTESTCD, PPORRES)
# Li 2019 Table 3, 'Patient population' block. Ceftazidime Cmax,ss / AUCss,0-24
# then avibactam Cmax,ss / AUCss,0-24.
refTable3 <- tribble(
~group, ~cmax, ~auclast,
"Ceftazidime / cUTI", 77.9, 979,
"Ceftazidime / cIAI", 66.9, 749,
"Ceftazidime / NP", 72.9, 950,
"Avibactam / cUTI", 12.1, 138,
"Avibactam / cIAI", 12.8, 132,
"Avibactam / NP", 14.2, 169
)
cmp <- nlmixr2lib::ncaComparisonTable(
simGeo, refTable3,
by = "group",
units = c(cmax = "mg/L", auclast = "mg*h/L"),
tolerance_pct = 25,
label_first_column = "NCA parameter"
)
cmp |>
dplyr::rename(`Analyte / indication` = group) |>
knitr::kable(caption = "Simulated geometric means against Li 2019 Table 3 (individual predicted steady-state exposures in actual Phase 3 patients). Rows differing by more than 25% are starred.")| NCA parameter | Analyte / indication | Reference | Simulated | % diff |
|---|---|---|---|---|
| Cmax (mg/L) | Ceftazidime / cUTI | 77.9 | 75 | -3.7% |
| Cmax (mg/L) | Ceftazidime / cIAI | 66.9 | 70 | +4.6% |
| Cmax (mg/L) | Ceftazidime / NP | 72.9 | 74.7 | +2.5% |
| Cmax (mg/L) | Avibactam / cUTI | 12.1 | 12.1 | +0.1% |
| Cmax (mg/L) | Avibactam / cIAI | 12.8 | 13.6 | +6.4% |
| Cmax (mg/L) | Avibactam / NP | 14.2 | 14.3 | +0.6% |
| AUClast (mg*h/L) | Ceftazidime / cUTI | 979 | 952 | -2.8% |
| AUClast (mg*h/L) | Ceftazidime / cIAI | 749 | 828 | +10.5% |
| AUClast (mg*h/L) | Ceftazidime / NP | 950 | 998 | +5.0% |
| AUClast (mg*h/L) | Avibactam / cUTI | 138 | 138 | +0.0% |
| AUClast (mg*h/L) | Avibactam / cIAI | 132 | 150 | +13.6% |
| AUClast (mg*h/L) | Avibactam / NP | 169 | 159 | -5.7% |
attr(cmp, "footnote")
#> NULL
# The simulated cohort reconstructs the paper's covariate distribution from
# published marginal counts, not from the patient-level data, so the two sides
# differ by a genuine physical mechanism (which subjects drew which renal
# function) rather than by numerical error. Assert on the CENTRE and on a
# robust quantile, never on the extreme.
#
# The comparison is recomputed from the two source frames rather than parsed
# back out of `cmp$"% diff"`, which is a formatted character column carrying a
# trailing "*" on flagged rows.
pctDiff <- refTable3 |>
pivot_longer(c(cmax, auclast), names_to = "PPTESTCD", values_to = "Reference") |>
left_join(simGeo, by = c("group", "PPTESTCD")) |>
mutate(pct = 100 * abs(PPORRES - Reference) / Reference)
stopifnot(
nrow(pctDiff) == 12L,
all(is.finite(pctDiff$pct)),
median(pctDiff$pct) < 15,
quantile(pctDiff$pct, 0.9) < 30
)Joint PK/PD target attainment
The paper’s headline result. The joint target is simultaneous achievement of free ceftazidime above 8 mg/L and free avibactam above 1 mg/L for at least 50% of each dosing interval, with free concentrations taken as 85% and 92% of total respectively (Methods, ‘PK/PD targets’ and ‘Exposure-response analysis’).
FU_CAZ <- 0.85
FU_AVI <- 0.92
MIC_CAZ <- 8
CT_AVI <- 1
# Fraction of the window spent above a threshold. The window is a whole number
# of identical steady-state intervals, so the fraction over 0-24 h equals the
# fraction over one dosing interval.
fracAbove <- function(time, conc, thresh) {
ok <- !is.na(conc)
mean(conc[ok] > thresh)
}
attain <- sim |>
mutate(free = Cc * ifelse(drug == "Ceftazidime", FU_CAZ, FU_AVI)) |>
group_by(id, indication, drug) |>
summarise(
fT = fracAbove(time, free, ifelse(drug[1] == "Ceftazidime", MIC_CAZ, CT_AVI)),
.groups = "drop"
) |>
pivot_wider(names_from = drug, values_from = fT) |>
mutate(joint = Ceftazidime >= 0.5 & Avibactam >= 0.5)
ptaSummary <- attain |>
group_by(indication) |>
summarise(
n = n(),
`Median %fT > 8 mg/L (CAZ)` = round(100 * median(Ceftazidime), 1),
`Median %fT > 1 mg/L (AVI)` = round(100 * median(Avibactam), 1),
`Joint target attainment, %` = round(100 * mean(joint), 1),
.groups = "drop"
) |>
dplyr::rename(Indication = indication)
ptaSummary |>
knitr::kable(caption = "Simulated joint PK/PD target attainment. Li 2019 Table 3 reports 98.6% (cIAI), 98.5% (cUTI) and 99.0% (NP) in actual Phase 3 patients; Table 4 reports 94.9-98.3% across the same indications in simulated patients with normal renal function.")| Indication | n | Median %fT > 8 mg/L (CAZ) | Median %fT > 1 mg/L (AVI) | Joint target attainment, % |
|---|---|---|---|---|
| NP | 200 | 100 | 100 | 98.5 |
| cIAI | 200 | 100 | 100 | 96.5 |
| cUTI | 200 | 100 | 100 | 99.0 |
# Li 2019 Results: attainment 'was > 97% for cIAI, cUTI, and NP' in Table 3 and
# '> 94.9%' across every simulated subgroup in Table 4. The bound is set at 90%
# so it is robust to which subjects the cohort draws while still failing loudly
# if the free-fraction, threshold or unit handling is wrong -- getting any of
# those wrong moves attainment by tens of percent, not by a few.
stopifnot(all(ptaSummary$`Joint target attainment, %` >= 90))
# Almost all individual values should be near-complete coverage: Li 2019
# Results reports that 'almost all individual ceftazidime %fT > MIC ... and
# avibactam %fT > CT values were close to 100%'.
stopifnot(median(attain$Ceftazidime) > 0.9, median(attain$Avibactam) > 0.9)The reconstructed cohort reproduces Table 3 closely: every one of the twelve exposure comparisons falls within about 15%, with a median absolute difference near 5%, and joint attainment lands within two percentage points of the published rate for each indication. Given that the cohort is rebuilt from published marginal counts rather than from patient-level data, that is about as close as this comparison can get.
Attainment is high for the same reason Li 2019 gives: the targets are modest relative to the exposures the 2000-500 mg q8h regimen produces, and the renal-function dose adjustments keep exposure roughly flat across the renal bands. This is also why the paper found no exposure-response relationship for microbiological outcome – there is essentially no unexposed stratum to contrast against.
Assumptions and deviations
Errata and internal inconsistencies in the source.
-
A published correction applies to Table 4. The
article carries the notice “Correction updated on October 26, 2018,
after initial online publication: The headings ‘Ceftazidime’ and
‘Avibactam’ in the top row of Table 4 were transposed.” In the corrected
copy used here the normal-renal-function rows are self-consistent – the
cIAI row’s
AUCss,0-24of 683 mg*h/L reproduces as 3 x 2000 / (6.95 x 1.030 x 1.16) = 722 – but the ESRD rows cannot be reconciled with either column assignment under the model as published. Table 4 is therefore used only for orientation; the quantitative gate above is built on Table 3, which the correction does not touch and whose drug assignment is unambiguous because the two analytes’ exposures differ roughly six-fold. -
Avibactam theta5 is a multiplier, not an absolute
clearance. Table 2 labels it “CL estimate for patients with
ESRD = 0.0678” and the Results text says “CL was 0.0678 L/h off
dialysis”. Both readings are wrong: the control stream uses it as
CLESRD = THETA(5)feedingCLT1 = THETA(1)*CLPP*CLESRD, giving 10.2 x 0.0678 = 0.692 L/h. Three checks agree on the multiplicative reading – an absolute 0.0678 L/h implies a terminal half-life of about six days; 0.692 L/h reproduces Table 4’s ESRD avibactamAUCss,0-24of 187.5 / (0.692 x 2) = 136 mg*h/L against the 127-168 printed; and the successor modelXie_2025_aztreonam_avibactam.Restimates the same effect as leaving 7.7% of reference clearance against 6.78% here. -
The ceftazidime body-weight percentages in the Results prose
do not reproduce. The text reports “24% lower and 26% higher
Vc” at 50 kg and 94 kg against a 70 kg median, but
(50/70)^1.01 = 0.712and(94/70)^1.01 = 1.347give 28.8% lower and 34.7% higher. Recovering the printed figures would need an exponent near 0.80 rather than the tabulated 1.01. The equation is taken as authoritative over the prose, per the standing policy, and the identical sentence in the avibactam Results does reproduce exactly ((51/70)^1.08 = 0.710 and (95/70)^1.08 = 1.391 against “29% lower” and “39% higher”), which is what identifies the ceftazidime sentence as the unreliable one. The covariate-effect table above therefore gates the avibactam weight effect but not the ceftazidime one. -
Ceftazidime “12.5% increase in CL per 100 mL/min above 100
mL/min” is the absolute increment
100 x 0.00125182 = 0.125read as a percentage. Because this model’s renal factor is 1.030 at the hinge rather than 1, the increment as a relative rise in clearance is 12.1%. The gate above is written on the slope itself, so it is insensitive to which reading is meant. -
Table 2 misprints theta12’s formula as
Vc*(1 + theta11); the control stream confirms theta12.
Encoding decisions.
- Two model files, one vignette. The two analytes were fitted separately, to different data sets, with different retained covariates. They are extracted as two files per the library’s policy of replicating the authors’ model structure, and the joint PK/PD analysis that couples them lives here in the vignette, which is where Li 2019 puts it too.
-
The creatinine-clearance slopes are encoded
fixed()in the ceftazidime model. They are hard-coded constants in the final control stream (SLOPE1=0.01030360,SLOPE2=0.00125182, under the comment;SCALED SO THAT TVCL = 7.07 (HS)), even though Table 1 quotes an RSE for each; the RSEs belong to the earlier estimation step that produced them. -
Concentrations are in mg/L, not the control stream’s
ng/mL. The source sets
S1 = V1/1000with doses in mg. Every additive residual standard deviation is therefore divided by 1000 on the way in; the proportional terms are dimensionless and carry over unchanged. Li 2019’s own exposure tables and PK/PD targets are stated in mg/L, so this is also the more natural unit for the packaged model. - Residual error is phase-switched, not collapsed. Both models carry every published stratum: ceftazidime has a Phase 1 and a pooled Phase 2/3 stratum, avibactam has three separate strata, and only the Phase 1 strata carry an additive component. The ceftazidime Phase 2/3 additive term has an RSE of 447% and is effectively unidentified, but it is retained rather than dropped because the paper reports it.
-
Residual scales differ between the two models and are
handled differently. Li 2019 Table 1 marks its residual rows
“Reported as variance” and they are square-rooted; Table 2 does not, and
its residual thetas are on the standard-deviation scale already
(
$SIGMA 1 FIXwithW = SQRT(WA1**2 + (WP1*IPRED)**2)), so they are used verbatim.
Cohort reconstruction assumptions. These affect the Table 3 comparison only, not the model files.
- Creatinine clearance is sampled from Table 3’s published band counts, uniformly within each band, and applied identically to all three indications. The real indication cohorts had somewhat different renal distributions, which the marginal counts in Table 3 do not resolve.
-
Acute pyelonephritis is held at 0 for the cUTI arm.
Li 2019 does not report what fraction of its cUTI subjects had AP, and
inventing a prevalence would be worse than omitting it. The effect is a
18.5% reduction in ceftazidime Vc, so the simulated cUTI
Cmaxis biased slightly high relative to the real cohort. -
MECH_VENTis set equal to the VAP indicator. Li 2019 defines NPv as a ventilator in the room on the PK sampling day, which “includes patients with VAP or HAP who were ventilated”, so flagging only the VAP subjects is a lower bound on the true NPv count; the paper does not report how many HAP patients were ventilated on the sampling day. - Body weight is drawn lognormally with a median of 70 kg and a log standard deviation of 0.23, chosen so the 10th and 90th percentiles land near the 50 kg and 94 kg that Li 2019 Results quotes, and truncated to 40-150 kg.
-
RENAL_ARC,RENALIMP_ESRDandRRT_HEMODIAL_STATUSare all 0 in the simulated cohort, which is correct: ARC was recorded only in the Phase 1 study CXL-PK-04, and the Phase 3 exposures of Table 3 contain no ESRD or dialysis patients. Those three terms are exercised by the deterministic covariate-effect table instead. -
Percentage of the interval above target is computed on a 0.1
h grid, so
%fThas a resolution of about 0.4%. The attainment gate has 40 percentage points of headroom, so the discretisation is immaterial.