Skip to contents

Model 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').")
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).")
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.")
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.")
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.")
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.")
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.")
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.

  1. 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-24 of 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.
  2. 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) feeding CLT1 = 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 avibactam AUCss,0-24 of 187.5 / (0.692 x 2) = 136 mg*h/L against the 127-168 printed; and the successor model Xie_2025_aztreonam_avibactam.R estimates the same effect as leaving 7.7% of reference clearance against 6.78% here.
  3. 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.712 and (94/70)^1.01 = 1.347 give 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.
  4. Ceftazidime “12.5% increase in CL per 100 mL/min above 100 mL/min” is the absolute increment 100 x 0.00125182 = 0.125 read 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.
  5. Table 2 misprints theta12’s formula as Vc*(1 + theta11); the control stream confirms theta12.

Encoding decisions.

  1. 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.
  2. 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.
  3. Concentrations are in mg/L, not the control stream’s ng/mL. The source sets S1 = V1/1000 with 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.
  4. 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.
  5. 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 FIX with W = 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.

  1. 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.
  2. 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 Cmax is biased slightly high relative to the real cohort.
  3. MECH_VENT is 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.
  4. 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.
  5. RENAL_ARC, RENALIMP_ESRD and RRT_HEMODIAL_STATUS are 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.
  6. Percentage of the interval above target is computed on a 0.1 h grid, so %fT has a resolution of about 0.4%. The attainment gate has 40 percentage points of headroom, so the discretisation is immaterial.