Skip to contents

Model and source

  • Citation: Ji X-w, Mak WY, Xue F, Yang W-y, Kuan IH-S, Xiang X-q, Li Y, Zhu X. Population pharmacokinetics and pulmonary modeling of eravacycline and the determination of microbiological breakpoint and cutoff of PK/PD. Antimicrob Agents Chemother. 2025;69(3):e01065-24. doi:10.1128/aac.01065-24
  • Description: Three-compartment intravenous population PK model for eravacycline in healthy adult volunteers (Ji 2025), fitted jointly to total plasma concentrations and to urea-corrected epithelial lining fluid (ELF) concentrations derived from bronchoalveolar lavage. ELF is not a kinetic compartment: under the authors’ quasi-equilibrium simplification the unbound ELF concentration is the unbound plasma concentration times an estimated ELF distribution ratio of 8.26. Unbound plasma concentration follows a fixed nonlinear power function of total concentration (Cu = 0.141 * Ctot^0.873, mg/L) carried from published binding data. Body weight enters allometrically (fixed exponents 0.75 on clearances and 1 on volumes, referenced to the 81.4 kg cohort median); no other covariate was retained.
  • Article: https://doi.org/10.1128/aac.01065-24

Ji and colleagues re-analysed the Phase I bronchopulmonary-disposition study of intravenous eravacycline (TP-434-006) to build a population PK model of total plasma and epithelial lining fluid (ELF) concentrations, and used it in a Monte Carlo probability-of-target-attainment (PTA) analysis that proposes PK/PD cutoffs for four respiratory pathogens.

The final model (supplement Table S1, model 6) is a three-compartment disposition model with allometric body-weight scaling. ELF was first modelled as a kinetic compartment exchanging unbound drug with the central compartment (rate constants k_cl and k_lc, Figure 2 and supplement eq. 5-8), but with one bronchoalveolar lavage (BAL) per subject those rate constants could not be estimated. The authors therefore assumed quasi-equilibrium (dA_ELF/dt = 0, supplement eq. 10), under which the two ELF flux terms in the central ODE cancel exactly and the unbound ELF concentration becomes

C_ELF = Ratio * C_u,     C_u = 0.141 * C_tot^0.873   (mg/L)

with Ratio = 8.26 estimated and the unbound plasma concentration C_u obtained from total concentration through a fixed power-law binding relationship taken from published binding data (supplement eq. 1). The packaged model therefore has three ODE states and two outputs: total plasma Cc and unbound ELF Celf. The unbound plasma concentration is returned as Cu.

Population

mod_fun <- readModelDb("Ji_2025_eravacycline")
str(rxode2::rxode(mod_fun)$population)
#> ℹ parameter labels from comments will be replaced by 'label()'
#> List of 14
#>  $ species       : chr "human"
#>  $ n_subjects    : num 20
#>  $ n_studies     : num 1
#>  $ age_range     : chr "19-47 years"
#>  $ age_median    : chr "27.5 years"
#>  $ weight_range  : chr "49.4-105 kg"
#>  $ weight_median : chr "81.4 kg"
#>  $ sex_female_pct: num 35
#>  $ race_ethnicity: Named num [1:2] 75 25
#>   ..- attr(*, "names")= chr [1:2] "Caucasian" "Other"
#>  $ disease_state : chr "healthy volunteers"
#>  $ dose_range    : chr "1 mg/kg IV over 1 h every 12 h for 7 doses"
#>  $ regions       : chr "United States (Phase I study TP-434-006, NCT01989949)"
#>  $ sampling      : chr "Plasma before and 1, 2, 4, 6 and 12 h after the last dose; one bronchoalveolar lavage per subject at 1, 2, 4, 6"| __truncated__
#>  $ notes         : chr "Ji 2025 Table 5 (demographics), Methods, and supplement section 'Human PK data collection'."

Twenty healthy volunteers (13 male, 7 female; 15 Caucasian) aged 19-47 years (median 27.5) and weighing 49.4-105 kg (median 81.4) received seven 1-hour infusions of eravacycline 1 mg/kg every 12 hours (Ji 2025 Table 5, supplement ‘Human PK data collection’). Plasma was sampled before and 1, 2, 4, 6 and 12 h after the last dose; each subject contributed one BAL at one of the same times.

Source trace

Element Value Source
Structure: 3 compartments, quasi-equilibrium ELF – Supplement eq. 5-12; Table S1 model 6
lcl log(16.3 L/h) Table 1
lvc log(3.88 L) Table 1
lq log(33.9 L/h) Table 1 (Q1)
lvp log(39 L) Table 1 (Vp1)
lq2 log(23.5 L/h) Table 1 (Q2)
lvp2 log(122 L) Table 1 (Vp2)
lfelf log(8.26) Table 1 (‘Ratio’); supplement eq. 12
fucoef, fupow 0.141, 0.873 (fixed) Supplement eq. 1 and 9
e_wt_cl, e_wt_q, e_wt_q2 0.75 (fixed) Table 1 footnote a
e_wt_vc, e_wt_vp, e_wt_vp2 1 (fixed) Table 1 footnote a
Reference weight 81.4 kg Table 1 footnote a; Table 5 median
etalcl log(1 + 0.136^2) Table 1 IIV CL 13.6%
etalvc log(1 + 1.16^2) Table 1 IIV Vc 116%
etalvp log(1 + 0.55^2) Table 1 IIV Vp1 55%
propSd 0.0704 Table 1 serum proportional error 7.04%
addSd 8.73 / 1000 mg/L Table 1 serum additive error 8.73 (read as ng/mL)
propSd_Celf 0.423 Table 1 BAL proportional error 42.3%

Typical-value checks

Two deterministic checks run before any cohort is simulated. First, the quasi-equilibrium simplification leaves plasma disposition linear, so the steady-state total AUC over a day must equal the daily dose divided by clearance exactly. Second, the Methods quote an unbound plasma AUC of 1.5 mg*h/L for the approved 1 mg/kg q12h regimen (attributed to the bronchopulmonary study, reference 8 of the paper); the power-law binding plus the model’s clearance should land on it for a typical 81.4 kg subject.

mod <- rxode2::rxode(mod_fun)
#> ℹ parameter labels from comments will be replaced by 'label()'
mod_typ <- rxode2::zeroRe(mod)

wt_typ <- 81.4
ev_typ <- bind_rows(
  data.frame(
    id = 1L, time = seq(0, 156, by = 12), evid = 1L, amt = wt_typ,
    dur = 1, cmt = "central", dvid = NA_integer_
  ),
  data.frame(
    id = 1L, time = sort(unique(c(seq(0, 168, by = 1), seq(144, 168, by = 0.05)))),
    evid = 0L, amt = NA_real_, dur = NA_real_, cmt = "central", dvid = 1L
  )
) |>
  mutate(WT = wt_typ) |>
  arrange(id, time, desc(evid))

sim_typ <- as.data.frame(rxode2::rxSolve(mod_typ, ev_typ, useLinCmt = FALSE))
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp'

trap <- function(t, y) sum(diff(t) * (head(y, -1) + tail(y, -1)) / 2)
day7 <- dplyr::filter(sim_typ, time >= 144)
typ <- data.frame(
  quantity = c("Total AUC24,ss (mg*h/L)", "Unbound plasma AUC24,ss (mg*h/L)", "Unbound ELF AUC24,ss (mg*h/L)"),
  simulated = c(trap(day7$time, day7$Cc), trap(day7$time, day7$Cu), trap(day7$time, day7$Celf)),
  expected = c(2 * wt_typ / 16.3, 1.5, NA)
)
knitr::kable(typ, digits = 3)
quantity simulated expected
Total AUC24,ss (mg*h/L) 9.988 9.988
Unbound plasma AUC24,ss (mg*h/L) 1.536 1.500
Unbound ELF AUC24,ss (mg*h/L) 12.687 NA

stopifnot(
  # Closed form: AUC over a dosing day at steady state = daily dose / CL.
  abs(typ$simulated[1] / typ$expected[1] - 1) < 0.005,
  # Unbound plasma exposure quoted in the Methods for 1 mg/kg q12h.
  abs(typ$simulated[2] / typ$expected[2] - 1) < 0.10
)

The unbound ELF exposure of the typical subject is about 12.7 mgh/L, so at an MIC of 4 mg/L the typical subject sits at fAUC/MIC of about 3.2, just above the E. coli* target of 3. That is why the published PTA for the approved regimen at MIC 4 mg/L is neither 0% nor 100% (63.3%, supplement Table S5(A)).

Virtual cohort and regimens

The Monte Carlo analysis drew body weight from a uniform distribution between 50 and 100 kg (supplement ‘Dose optimization via Monte Carlo simulations’) and simulated the five regimens of Table 6 for seven days, computing the PTA from the unbound AUC at steady state. Here 200 virtual subjects are simulated per regimen; the same weights are reused across regimens.

rxode2::rxSetSeed(20250129)
n_per_arm <- 200
wt_cohort <- runif(n_per_arm, 50, 100)

regimens <- list(
  "Regimen 1" = list(times = seq(0, 156, by = 12), mgkg = rep(1, 14), dur = 1),
  "Regimen 2" = list(times = seq(0, 156, by = 12), mgkg = rep(1.5, 14), dur = 2),
  "Regimen 3" = list(times = seq(0, 144, by = 24), mgkg = rep(1.5, 7), dur = 2),
  "Regimen 4" = list(times = c(0, 12, seq(24, 144, by = 24)), mgkg = rep(1.5, 8), dur = 2),
  "Regimen 5" = list(times = seq(0, 156, by = 12), mgkg = c(1.5, 1.5, rep(1, 12)), dur = 2)
)

obs_times <- sort(unique(c(seq(0, 144, by = 2), seq(144, 168, by = 0.25))))

make_events <- function(k) {
  reg <- regimens[[k]]
  ids <- (k - 1L) * n_per_arm + seq_len(n_per_arm)
  doses <- tidyr::crossing(data.frame(id = ids, WT = wt_cohort), data.frame(time = reg$times, mgkg = reg$mgkg)) |>
    mutate(
      evid = 1L, amt = mgkg * WT, dur = reg$dur,
      cmt = "central", dvid = NA_integer_
    ) |>
    select(-mgkg)
  obs <- tidyr::crossing(data.frame(id = ids, WT = wt_cohort), data.frame(time = obs_times)) |>
    mutate(
      evid = 0L, amt = NA_real_, dur = NA_real_,
      cmt = "central", dvid = 1L
    )
  bind_rows(doses, obs) |>
    mutate(regimen = names(regimens)[k])
}

events <- bind_rows(lapply(seq_along(regimens), make_events)) |>
  arrange(id, time, desc(evid)) |>
  select(id, time, evid, amt, dur, cmt, dvid, WT, regimen)

sim <- as.data.frame(rxode2::rxSolve(
  mod, events,
  keep = c("regimen", "WT"), useLinCmt = FALSE
))
stopifnot(length(unique(sim$id)) == length(regimens) * n_per_arm)

Replicating Figure 5: concentrations after the last study dose

Figure 5 of the paper shows the plasma and BAL-derived ELF concentrations over the 12 h after the seventh (last) dose of 1 mg/kg q12h. The approved regimen (regimen 1) of the virtual cohort is plotted over the same post-dose window of its own final dosing interval (156-168 h).

last_int <- sim |>
  filter(regimen == "Regimen 1", time >= 156) |>
  mutate(tad = time - 156) |>
  select(id, tad, `Total plasma` = Cc, `Unbound ELF` = Celf) |>
  pivot_longer(c(`Total plasma`, `Unbound ELF`), names_to = "matrix", values_to = "conc") |>
  group_by(matrix, tad) |>
  summarise(
    p05 = quantile(conc, 0.05), p50 = median(conc), p95 = quantile(conc, 0.95),
    .groups = "drop"
  )

ggplot(last_int, aes(tad, p50)) +
  geom_ribbon(aes(ymin = p05, ymax = p95), alpha = 0.25, fill = "steelblue") +
  geom_line(colour = "steelblue4") +
  facet_wrap(~matrix, scales = "free_y") +
  scale_y_log10() +
  labs(x = "Time after last dose (h)", y = "Eravacycline (mg/L)")
Replicates the layout of Figure 5 (plasma) and Figure S2 (ELF) of Ji 2025: median and 90% prediction interval after the last dose of 1 mg/kg q12h.

Replicates the layout of Figure 5 (plasma) and Figure S2 (ELF) of Ji 2025: median and 90% prediction interval after the last dose of 1 mg/kg q12h.

PKNCA: unbound exposure on day 7

The PK/PD index of the paper is the unbound AUC at steady state. PKNCA computes it over the last 24 h of the seventh day (144-168 h) for the unbound plasma (Cu) and unbound ELF (Celf) concentrations, grouped by regimen.

dose_df <- events |>
  filter(evid == 1L) |>
  select(id, time, amt, regimen)

conc_cu <- sim |>
  filter(!is.na(Cu)) |>
  select(id, time, Cu, regimen)
conc_elf <- sim |>
  filter(!is.na(Celf)) |>
  select(id, time, Celf, regimen)

intervals <- data.frame(start = 144, end = 168, auclast = TRUE, cmax = TRUE)

nca_cu <- pk.nca(PKNCAdata(
  PKNCAconc(conc_cu, Cu ~ time | regimen + id),
  PKNCAdose(dose_df, amt ~ time | regimen + id),
  intervals = intervals
))
nca_elf <- pk.nca(PKNCAdata(
  PKNCAconc(conc_elf, Celf ~ time | regimen + id),
  PKNCAdose(dose_df, amt ~ time | regimen + id),
  intervals = intervals
))

nca_tab <- bind_rows(
  as.data.frame(nca_cu$result) |> mutate(matrix = "Unbound plasma"),
  as.data.frame(nca_elf$result) |> mutate(matrix = "Unbound ELF")
) |>
  group_by(matrix, regimen, PPTESTCD) |>
  summarise(median = median(PPORRES), .groups = "drop") |>
  pivot_wider(names_from = PPTESTCD, values_from = median)

nca_tab |>
  dplyr::rename(
    Matrix = matrix, Regimen = regimen,
    "Median fAUC144-168 (mg*h/L)" = auclast, "Median fCmax (mg/L)" = cmax
  ) |>
  knitr::kable(digits = 3, caption = "Median day-7 unbound exposure by regimen.")
Median day-7 unbound exposure by regimen.
Matrix Regimen Median fAUC144-168 (mg*h/L) Median fCmax (mg/L)
Unbound ELF Regimen 1 12.421 1.757
Unbound ELF Regimen 2 18.058 1.746
Unbound ELF Regimen 3 9.390 1.543
Unbound ELF Regimen 4 9.716 1.573
Unbound ELF Regimen 5 12.483 1.246
Unbound plasma Regimen 1 1.504 0.213
Unbound plasma Regimen 2 2.186 0.211
Unbound plasma Regimen 3 1.137 0.187
Unbound plasma Regimen 4 1.176 0.190
Unbound plasma Regimen 5 1.511 0.151

The only steady-state NCA value the paper states is the unbound plasma AUC of 1.5 mg*h/L for the approved regimen (Methods, ‘Determination of PK/PD target values’).

published <- data.frame(regimen = "Regimen 1", auclast = 1.5)
simulated_r1 <- as.data.frame(nca_cu$result) |>
  filter(regimen == "Regimen 1")

cmp <- nlmixr2lib::ncaComparisonTable(
  simulated     = simulated_r1,
  reference     = published,
  by            = "regimen",
  params        = "auclast",
  units         = c(auclast = "mg*h/L"),
  tolerance_pct = 20
)
knitr::kable(cmp, caption = "Simulated vs. Ji 2025 Methods: unbound plasma AUC24,ss for 1 mg/kg q12h. * differs by >20%.")
Simulated vs. Ji 2025 Methods: unbound plasma AUC24,ss for 1 mg/kg q12h. * differs by >20%.
NCA parameter regimen Reference Simulated % diff
AUClast (mg*h/L) Regimen 1 1.5 1.5 +0.2%

Replicating supplement Table S5: probability of target attainment

PTA is the percentage of subjects whose unbound ELF AUC over day 7 divided by the MIC reaches the target (supplement eq. 17-18). The paper’s tables for E. coli (target 3) and for K. pneumoniae (targets 6 and 10) are reproduced below; the A. baumannii and S. aureus tables at target 10 are identical to the K. pneumoniae target-10 table over the shared MIC range.

fauc_elf <- as.data.frame(nca_elf$result) |>
  filter(PPTESTCD == "auclast") |>
  select(id, regimen, fauc = PPORRES)

mics <- c(0.004, 0.008, 0.016, 0.03, 0.06, 0.12, 0.25, 0.5, 1, 2, 4, 8, 16)
pta_sim <- tidyr::crossing(fauc_elf, mic = mics, target = c(3, 6, 10)) |>
  group_by(regimen, target, mic) |>
  summarise(pta = 100 * mean(fauc / mic >= target), .groups = "drop")

# Supplement Table S5(A) (target 3) and S5(B) (targets 10 and 6), MIC 0.03-16 mg/L.
pub_mic <- c(0.03, 0.06, 0.12, 0.25, 0.5, 1, 2, 4, 8, 16)
pub_t3 <- cbind(
  "Regimen 1" = c(100, 100, 100, 100, 100, 100, 100, 63.3, 0, 0),
  "Regimen 2" = c(100, 100, 100, 100, 100, 100, 100, 100, 1, 0),
  "Regimen 3" = c(100, 100, 100, 100, 100, 100, 99.9, 3.1, 0, 0),
  "Regimen 4" = c(100, 100, 100, 100, 100, 100, 100, 4.2, 0, 0),
  "Regimen 5" = c(100, 100, 100, 100, 100, 100, 100, 60.8, 0, 0)
)
pub_t10 <- cbind(
  "Regimen 1" = c(100, 100, 100, 100, 100, 95.1, 0, 0, 0, 0),
  "Regimen 2" = c(100, 100, 100, 100, 100, 100, 18.4, 0, 0, 0),
  "Regimen 3" = c(100, 100, 100, 100, 100, 38.2, 0, 0, 0, 0),
  "Regimen 4" = c(100, 100, 100, 100, 100, 38.2, 0, 0, 0, 0),
  "Regimen 5" = c(100, 100, 100, 100, 100, 95.9, 0, 0, 0, 0)
)
pub_t6 <- cbind(
  "Regimen 1" = c(100, 100, 100, 100, 100, 100, 63.3, 0, 0, 0),
  "Regimen 2" = c(100, 100, 100, 100, 100, 100, 100, 1, 0, 0),
  "Regimen 3" = c(100, 100, 100, 100, 100, 99.9, 3.1, 0, 0, 0),
  "Regimen 4" = c(100, 100, 100, 100, 100, 100, 4.2, 0, 0, 0),
  "Regimen 5" = c(100, 100, 100, 100, 100, 100, 60.8, 0, 0, 0)
)
to_long <- function(m, target) {
  as.data.frame(m) |>
    mutate(mic = pub_mic) |>
    pivot_longer(-mic, names_to = "regimen", values_to = "pta_pub") |>
    mutate(target = target)
}
pta_pub <- bind_rows(to_long(pub_t3, 3), to_long(pub_t6, 6), to_long(pub_t10, 10))

pta_cmp <- inner_join(pta_pub, pta_sim, by = c("regimen", "target", "mic"))

pta_cmp |>
  filter(mic >= 0.5, mic <= 8) |>
  mutate(cell = sprintf("%.1f / %.1f", pta_pub, pta)) |>
  select(target, mic, regimen, cell) |>
  pivot_wider(names_from = regimen, values_from = cell) |>
  dplyr::rename("fAUC/MIC target" = target, "MIC (mg/L)" = mic) |>
  knitr::kable(caption = "PTA (%), published / simulated, supplement Table S5. MICs at or below 0.25 mg/L are 100 / 100 throughout and MIC 16 mg/L is 0 / 0.")
PTA (%), published / simulated, supplement Table S5. MICs at or below 0.25 mg/L are 100 / 100 throughout and MIC 16 mg/L is 0 / 0.
fAUC/MIC target MIC (mg/L) Regimen 1 Regimen 2 Regimen 3 Regimen 4 Regimen 5
3 0.5 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0
3 1.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0
3 2.0 100.0 / 100.0 100.0 / 100.0 99.9 / 100.0 100.0 / 100.0 100.0 / 100.0
3 4.0 63.3 / 57.5 100.0 / 100.0 3.1 / 2.5 4.2 / 7.0 60.8 / 64.0
3 8.0 0.0 / 0.0 1.0 / 0.5 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0
6 0.5 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0
6 1.0 100.0 / 100.0 100.0 / 100.0 99.9 / 100.0 100.0 / 100.0 100.0 / 100.0
6 2.0 63.3 / 57.5 100.0 / 100.0 3.1 / 2.5 4.2 / 7.0 60.8 / 64.0
6 4.0 0.0 / 0.0 1.0 / 0.5 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0
6 8.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0
10 0.5 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0
10 1.0 95.1 / 94.0 100.0 / 100.0 38.2 / 29.0 38.2 / 42.5 95.9 / 97.0
10 2.0 0.0 / 0.0 18.4 / 25.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0
10 4.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0
10 8.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0 0.0 / 0.0

# Cells where the published PTA is neither 0% nor 100% carry the information;
# the saturated cells agree trivially.
partial <- filter(pta_cmp, pta_pub > 0, pta_pub < 100)
stopifnot(
  # Structural: a wrong binding exponent, ELF ratio or unit reading shifts every
  # partial cell by tens of percentage points.
  abs(median(partial$pta - partial$pta_pub)) < 5,
  quantile(abs(partial$pta - partial$pta_pub), 0.9) < 15
)
pta_sim |>
  filter((target == 3) | (target == 6)) |>
  mutate(panel = ifelse(target == 3, "E. coli, fAUC/MIC = 3", "K. pneumoniae, fAUC/MIC = 6")) |>
  filter(mic >= 0.03) |>
  ggplot(aes(mic, pta, colour = regimen)) +
  geom_line() +
  geom_point() +
  geom_hline(yintercept = 90, linetype = "dashed") +
  scale_x_log10() +
  facet_wrap(~panel) +
  labs(x = "MIC (mg/L)", y = "PTA (%)", colour = NULL)
Replicates Figure 6A-B of Ji 2025: PTA against E. coli at fAUC/MIC = 3 and K. pneumoniae at fAUC/MIC = 6.

Replicates Figure 6A-B of Ji 2025: PTA against E. coli at fAUC/MIC = 3 and K. pneumoniae at fAUC/MIC = 6.

Replicating Table 4: cumulative fraction of response

The CFR weights the PTA at each MIC by the fraction of the 500 clinical isolates with that MIC (Table 2; supplement eq. 19).

mic_dist <- bind_rows(
  data.frame(bug = "E. coli", target = 3, mic = c(0.03, 0.06, 0.12, 0.25, 0.5, 1, 2), n = c(9, 67, 223, 142, 41, 12, 6)),
  data.frame(bug = "K. pneumoniae", target = 6, mic = c(0.03, 0.06, 0.12, 0.25, 0.5, 1, 2, 4, 8, 16), n = c(1, 8, 66, 157, 165, 44, 38, 14, 6, 1)),
  data.frame(bug = "A. baumannii", target = 10, mic = c(0.004, 0.008, 0.016, 0.03, 0.06, 0.12, 0.25, 0.5, 1, 2, 4), n = c(23, 14, 63, 134, 72, 47, 29, 84, 22, 8, 4)),
  data.frame(bug = "S. aureus", target = 10, mic = c(0.004, 0.008, 0.016, 0.03, 0.06, 0.12, 0.25, 0.5, 1), n = c(1, 52, 134, 121, 114, 33, 14, 19, 12))
)
stopifnot(all(tapply(mic_dist$n, mic_dist$bug, sum) == 500))

cfr_sim <- mic_dist |>
  inner_join(pta_sim, by = c("target", "mic"), relationship = "many-to-many") |>
  group_by(bug, regimen) |>
  summarise(cfr = sum(pta * n) / sum(n), .groups = "drop")

cfr_pub <- data.frame(
  bug = rep(c("E. coli", "K. pneumoniae", "A. baumannii", "S. aureus"), each = 5),
  regimen = rep(names(regimens), 4),
  cfr_pub = c(
    100, 100, 100, 100, 100,
    93.0, 95.8, 88.4, 88.5, 92.8,
    97.4, 97.9, 94.9, 94.9, 97.4,
    99.9, 100, 98.5, 98.5, 99.9
  )
)
cfr_cmp <- inner_join(cfr_pub, cfr_sim, by = c("bug", "regimen"))

cfr_cmp |>
  mutate(cell = sprintf("%.1f / %.1f", cfr_pub, cfr)) |>
  select(bug, regimen, cell) |>
  pivot_wider(names_from = regimen, values_from = cell) |>
  dplyr::rename(Bacterium = bug) |>
  knitr::kable(caption = "CFR (%), published (Table 4) / simulated.")
CFR (%), published (Table 4) / simulated.
Bacterium Regimen 1 Regimen 2 Regimen 3 Regimen 4 Regimen 5
E. coli 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0 100.0 / 100.0
K. pneumoniae 93.0 / 92.6 95.8 / 95.8 88.4 / 88.4 88.5 / 88.7 92.8 / 93.1
A. baumannii 97.4 / 97.3 97.9 / 98.0 94.9 / 94.5 94.9 / 95.1 97.4 / 97.5
S. aureus 99.9 / 99.9 100.0 / 100.0 98.5 / 98.3 98.5 / 98.6 99.9 / 99.9

stopifnot(abs(median(cfr_cmp$cfr - cfr_cmp$cfr_pub)) < 2)

Assumptions and deviations

  • IIV scale. Table 1 reports IIV as bare percentages (13.6%, 116%, 55%) without saying whether they are the SD of eta or the lognormal CV. They are encoded as lognormal CVs, omega^2 = log(1 + CV^2). The PTA and CFR outputs cannot discriminate the two readings: they depend on clearance only, where the readings differ by 0.4%.
  • Additive residual error unit. Table 1 prints the serum additive error as 8.73 with no unit. It is read as ng/mL (8.73 / 1000 = 0.00873 mg/L): the bioanalytical calibration range is 5-500 ng/mL, and 8.73 mg/L would exceed the simulated peak concentrations. The rest of the model is in mg/L, which the binding equation requires (next item).
  • Binding-equation units. Supplement eq. 1 does not state units. With total concentration in mg/L it gives an unbound fraction of about 19% at 0.1 mg/L falling to about 10.5% at 10 mg/L, consistent with eravacycline’s reported 79-90% plasma protein binding; the unbound plasma AUC it produces matches the 1.5 mg*h/L quoted in the Methods, and the resulting PTA table matches supplement Table S5 (above).
  • Weight exponent. The Discussion states clearance scales with weight to the power 0.62 (Figure S1), whereas the model equations in Table 1 footnote a use 0.75. The 0.62 describes a post-hoc regression of individual clearance estimates on weight; the printed model equation (0.75) is encoded.
  • Figure 2 schematic. The schematic draws the ELF rate constants k_cl and k_lc; the final model replaces them by the quasi-equilibrium ratio and they have no value.
  • BQL ELF samples. The Results report 5 of 20 BAL samples below the quantification limit, while the Discussion says four subjects (20%). The authors handled them with the M3 method; the packaged model carries no censoring, so simulated ELF concentrations are uncensored.
  • ELF is unbound. Observed ELF concentrations (urea-corrected BAL) are treated as unbound drug because ELF protein concentrations are low (supplement ‘ELF concentration determined from BAL’); Celf is therefore Ratio * Cu, not Ratio * Cc.
  • Table 2 MIC header. The MIC column headed 0.16 in Table 2 lies between 0.008 and 0.03 and is read as 0.016 mg/L, the value used in Table S5(C-D).
  • Covariate screen. Age, albumin, ALT, creatinine clearance, total protein, red and white blood cell counts and sex were screened and none was retained (supplement Table S2); they are documented as excluded covariates.
  • Virtual cohort. 200 subjects per regimen (the paper does not state its Monte Carlo size), so the simulated PTA carries a binomial error of a few percentage points at intermediate values.