Skip to contents

Model and source

#> ℹ parameter labels from comments will be replaced by 'label()'
  • Citation: Baklouti S, Rigourd V, Panchaud A, Nordeng H, Allegaert K, Annaert P, Huang MC, Monfort A, Guidi M, Gandia P. Population pharmacokinetic modelling of amoxicillin in human breast milk - A contribution from the ConcePTION project. Br J Clin Pharmacol. 2026;92(6):1833-1844. doi:10.1002/bcp.70434. All parameter values are the final estimates of Table 3; the ODE system and the Vmilk = Vc assumption are the display equations and prose of Results section 3.2 (pp. 1836-1837), and the model topology is Figure 1.

  • Description: Population PK model of oral amoxicillin in breastfeeding women, describing maternal plasma and breast-milk concentrations simultaneously. A gastrointestinal depot feeds a central (plasma) compartment by first-order absorption; the central compartment is drained both by first-order systemic elimination and by a UNIDIRECTIONAL first-order transfer into a breast-milk compartment, and milk is cleared by its own first-order loss constant. Nothing returns from milk to plasma: the authors tested a bidirectional peripheral-milk parameterisation and it failed to converge. The milk volume is not identifiable from the data and was fixed equal to the central volume, so the milk state is scaled by V/F. Because the milk loss constant runs continuously rather than only at feeds, the model understates milk amounts between feeds and is therefore a conservative (low) estimator of the relative infant dose; the authors flag this as its main structural limitation. Inter-individual variability on all five structural parameters, separate proportional residual errors for plasma and for milk, and no retained covariates.

  • Article: https://doi.org/10.1002/bcp.70434

  • Supplement (Appendix S1, the LC-MS/MS validation report for amoxicillin in milk; it contains no model parameters).

This is the first population PK model of amoxicillin developed in breastfeeding women, and it is the amoxicillin arm of the European ConcePTION consortium. The consortium’s cetirizine model is modellib("Melander_2025_cetirizine").

Population

pop <- readModelDb("Baklouti_2026_amoxicillin")()$population
str(pop, max.level = 1)
#> List of 15
#>  $ species        : chr "human"
#>  $ n_subjects     : num 25
#>  $ n_studies      : num 1
#>  $ n_observations : num 150
#>  $ age_mean       : chr "35 years"
#>  $ weight_mean    : chr "64.9 kg"
#>  $ height_mean    : chr "164.5 cm"
#>  $ sex_female_pct : num 100
#>  $ renal_function : chr "Normal; CKD-EPI eGFR mean 114.7 mL/min/1.73 m^2 (SD 8.5, CV 7.4%). The narrow spread is why no renal covariate "| __truncated__
#>  $ disease_state  : chr "Breastfeeding women treated with oral immediate-release amoxicillin, with or without clavulanic acid, for at le"| __truncated__
#>  $ dose_range     : chr "Oral immediate-release amoxicillin 1 g twice daily (n = 6) or 1 g three times daily (n = 19); mean total daily "| __truncated__
#>  $ regions        : chr "France (recruited from the lactarium of Necker-Enfants Malades Hospital, Paris). EudraCT 2021-002247-30; French"| __truncated__
#>  $ infant_partner : chr "One breastfed infant per mother, all over 4 weeks old: 12 male / 13 female, mean postnatal age 5.5 months (SD 4"| __truncated__
#>  $ feeding_pattern: chr "Mothers reported a mean of 9 breastfeeds per day (SD 4, CV 47%; Table 1). The steady-state Monte Carlo simulati"| __truncated__
#>  $ notes          : chr "Baseline demographics from Baklouti 2026 Tables 1 and 2. Three blood and three milk samples per mother (75 + 75"| __truncated__

Twenty-five French breastfeeding mothers (mean age 35 years, mean weight 64.9 kg, mean CKD-EPI eGFR 114.7 mL/min/1.73 m^2) taking oral immediate-release amoxicillin 1 g twice daily (n = 6) or 1 g three times daily (n = 19) for at least two days, i.e. at steady state. Each contributed three plasma and three milk samples within a single dosing interval, nominally at 15-30 min, 1-2 h and 3-4 h post-dose, giving 75 + 75 = 150 observations (Baklouti 2026 Tables 1-2 and Results section 3.1). Milk was collected as roughly 20 mL of foremilk with an electric pump without emptying the breast; because amoxicillin is water-soluble and concentrates in low-fat foremilk, the authors describe this as a deliberate worst-case sampling scheme for milk exposure.

Source trace

Every value below is a final estimate from Baklouti 2026 Table 3. The per-parameter origin is also recorded as an in-file comment beside each ini() entry in inst/modeldb/specificDrugs/Baklouti_2026_amoxicillin.R.

Equation / parameter Value Source location
dG/dt = -ka*G, G(0) = F*D Results 3.2, display equations p. 1836; Figure 1
dX/dt = ka*G - ke*X - kmilk*X Results 3.2, display equations p. 1836; Figure 1
dM/dt = kmilk*X - kmilk_e*M Results 3.2, display equations p. 1836; Figure 1
C(t) = X(t)/Vc Results 3.2, display equation p. 1836
Vmilk = Vc identity Results 3.2, p. 1837 (“arbitrarily set to a value identical to that of the systemic compartment”)
lka 0.17 1/h Table 3, k a (h-1), RSE 39.9%, 95%CI 0.085-0.35
lvc 82.38 L Table 3, V/F (L), RSE 11.0%, 95%CI 66.46-102.1
lkel 0.31 1/h Table 3, K e (h-1), RSE 23.1%, 95%CI 0.2-0.48
lk_central_milk 0.028 1/h Table 3, K milk (h-1), RSE 12.5%, 95%CI 0.022-0.036
lkeff_milk 0.33 1/h Table 3, K milk_e (h-1), RSE 19.4%, 95%CI 0.23-0.48
etalka 0.37^2 Table 3, IIV k a (se), RSE 44.2%
etalvc 0.086^2 Table 3, IIV V/F (se), RSE 47.7%
etalkel 0.49^2 Table 3, IIV K e (se), RSE 24.9%
etalk_central_milk 0.11^2 Table 3, IIV K milk (se), RSE 64.8%
etalkeff_milk 0.38^2 Table 3, IIV K milk_e (se), RSE 28.3%
propSd (plasma) 0.48 Table 3, b1 (se), RSE 10.9%
propSd_Cmilk (milk) 0.26 Table 3, b2 (se), RSE 11.3%

The display equations render as <!-- formula-not-decoded --> in the markdown preprocessor, and the publisher’s symbol font encodes minus and multiplication as C0 control bytes, so the ODE signs above were recovered from the PDF with pdftotext -layout and cat -A. The sign that matters is on kmilk: it is subtracted from the central compartment as well as added to milk, so transfer into milk is a genuine elimination pathway for plasma and total plasma loss is ke + kmilk = 0.338 1/h.

mod$state
#> [1] "depot"   "central" "milk"

Validation 1 – the steady-state milk:plasma AUC ratio is a closed form

Integrating the milk ODE over a complete steady-state dosing interval makes the milk state return to where it started, so the accumulation term vanishes:

0 = kmilk * integral(central) - kmilk_e * integral(milk)

Because the model sets Vmilk = Vc, dividing through by that common volume turns the amount integrals into concentration AUCs and gives a ratio free of ka, ke and Vc altogether:

AUC(milk) / AUC(plasma) = kmilk / kmilk_e

That is a zero-parameter falsifier for the whole extraction. Baklouti 2026 Table 4 reports a simulated milk/plasma AUC ratio with median 8.5% and quartiles 6.6-11.1%.

theta <- c(kmilk = 0.028, kmilk_e = 0.33)
omega <- c(kmilk = 0.11, kmilk_e = 0.38)   # Table 3 IIV, read as log-scale SDs

ratio_median <- theta[["kmilk"]] / theta[["kmilk_e"]]

# The per-subject ratio is a ratio of two independent lognormals, so it is
# itself lognormal: its median is the ratio of the medians and its log-scale
# SD is the root-sum-square of the two omegas.
sd_log  <- sqrt(sum(omega^2))
ratio_q <- ratio_median * exp(qnorm(c(0.25, 0.75)) * sd_log)

data.frame(
  Quantity  = c("Median", "First quartile", "Third quartile"),
  Predicted = sprintf("%.2f%%", 100 * c(ratio_median, ratio_q)),
  Published = c("8.5%", "6.6%", "11.1%")
) |>
  knitr::kable(caption = "Closed-form milk/plasma AUC ratio vs Baklouti 2026 Table 4.")
Closed-form milk/plasma AUC ratio vs Baklouti 2026 Table 4.
Quantity Predicted Published
Median 8.48% 8.5%
First quartile 6.50% 6.6%
Third quartile 11.08% 11.1%

The agreement is essentially exact, and it is a strong test in both directions: it confirms the two milk rate constants, the Vmilk = Vc identity, and the unidirectional topology at once. It also settles a transcription question that Table 3 leaves open – whether the IIV column holds standard deviations or variances. Reading them as variances moves the predicted quartiles to 5.3-13.6%, well outside the published 6.6-11.1%:

sd_if_variances <- sqrt(sum(omega))   # counterfactual: treat 0.11 / 0.38 as variances

data.frame(
  Reading = c("IIV are log-scale SDs (used here)", "IIV are variances"),
  Q1 = sprintf("%.2f%%", 100 * ratio_median * exp(qnorm(0.25) * c(sd_log, sd_if_variances))),
  Q3 = sprintf("%.2f%%", 100 * ratio_median * exp(qnorm(0.75) * c(sd_log, sd_if_variances))),
  Published = "6.6% - 11.1%"
) |>
  knitr::kable(caption = "The published IQR discriminates between the two readings of Table 3's IIV column.")
The published IQR discriminates between the two readings of Table 3’s IIV column.
Reading Q1 Q3 Published
IIV are log-scale SDs (used here) 6.50% 11.08% 6.6% - 11.1%
IIV are variances 5.29% 13.60% 6.6% - 11.1%

The Discussion independently corroborates the SD reading: it quotes “a mean ka of 0.17 h-1 (CV = 37%)” against Table 3’s IIV k a of 0.37.

Virtual cohort and steady-state simulation

The model carries no covariates, so a cohort needs only the random effects. Table 4’s simulations use the maximum recommended maintenance dose from the summary of product characteristics, 2 g every 8 h (6 g/day). Dosing runs for five days so that even the slowest-absorbing and slowest-eliminating subjects are at steady state before the analysis interval.

Both Cc and Cmilk are declared endpoints of this model, so rxode2 returns each of them at every observation row and a single observation grid is enough.

Observation rows must name a declared endpoint (cmt = "Cc"), not an ODE state. This model has two error models, so its endpoints occupy compartments 4 and 5 and rxode2 rejects an observation that maps anywhere else: cmt = "central", cmt = "milk", cmt = 2, a bare dvid = 1L and an event table with no cmt at all each fail with 'dvid'->'cmt' on observation record or on a undefined compartment. This is the declared-endpoint case, which is legal and does not renumber anything – it is not the “referencing an algebraic observable injects a cmt() slot” trap, because Cc here is already a slot.

rxode2::rxSetSeed(20260902)

n_sub    <- 200        # per-arm cap; ample for this check
tau      <- 8          # h
n_dose   <- 15         # five days of q8h dosing
ss_start <- (n_dose - 1) * tau
ss_end   <- ss_start + tau

ev <- rxode2::et(amt = 2000, ii = tau, addl = n_dose - 1, cmt = "depot") |>
  rxode2::et(seq(ss_start, ss_end, by = 0.05), cmt = "Cc")

sim <- rxode2::rxSolve(
  mod, ev, nSub = n_sub,
  # rxode2's automatic ODE -> linCmt conversion corrupts multi-output models
  useLinCmt = FALSE
) |>
  as.data.frame() |>
  # a single-subject event table replicated with nSub names the subject
  # index `sim.id`; rename it so PKNCA and the plots can use `id`
  dplyr::rename(id = sim.id)

str(sim[, c("id", "time", "Cc", "Cmilk", "k_central_milk", "keff_milk")])
#> 'data.frame':    32200 obs. of  6 variables:
#>  $ id            : int  1 1 1 1 1 1 1 1 1 1 ...
#>  $ time          : num  112 112 112 112 112 ...
#>  $ Cc            : num  9.68 9.86 10.03 10.19 10.36 ...
#>  $ Cmilk         : num  1.06 1.05 1.05 1.05 1.05 ...
#>  $ k_central_milk: num  0.0263 0.0263 0.0263 0.0263 0.0263 ...
#>  $ keff_milk     : num  0.294 0.294 0.294 0.294 0.294 ...

Cc and Cmilk above are individual predictions (IPRED); no residual error is added, which is what the closed-form checks below require.

sim |>
  dplyr::select(id, time, Plasma = Cc, Milk = Cmilk) |>
  tidyr::pivot_longer(c(Plasma, Milk), names_to = "Matrix", values_to = "conc") |>
  dplyr::mutate(tad = time - ss_start) |>
  dplyr::group_by(Matrix, tad) |>
  dplyr::summarise(
    med = median(conc), lo = quantile(conc, 0.05), hi = quantile(conc, 0.95),
    .groups = "drop"
  ) |>
  ggplot2::ggplot(ggplot2::aes(tad, med, ymin = lo, ymax = hi, fill = Matrix, colour = Matrix)) +
  ggplot2::geom_ribbon(alpha = 0.25, colour = NA) +
  ggplot2::geom_line(linewidth = 0.8) +
  ggplot2::scale_y_log10() +
  ggplot2::labs(x = "Time after dose (h)", y = "Amoxicillin concentration (mg/L)") +
  ggplot2::theme_bw()
Simulated steady-state amoxicillin concentrations in maternal plasma and breast milk over one 8 h dosing interval at 2 g q8h (200 subjects; median and 5th-95th percentiles of the individual predictions). Milk concentrations sit roughly an order of magnitude below plasma and are visibly delayed and flattened relative to it, the behaviour shown by the prediction-corrected VPCs of Figure 4 of Baklouti 2026.

Simulated steady-state amoxicillin concentrations in maternal plasma and breast milk over one 8 h dosing interval at 2 g q8h (200 subjects; median and 5th-95th percentiles of the individual predictions). Milk concentrations sit roughly an order of magnitude below plasma and are visibly delayed and flattened relative to it, the behaviour shown by the prediction-corrected VPCs of Figure 4 of Baklouti 2026.

Validation 2 – PKNCA over the steady-state interval

nca_conc <- sim |>
  dplyr::select(id, time, Plasma = Cc, Milk = Cmilk) |>
  tidyr::pivot_longer(c(Plasma, Milk), names_to = "Matrix", values_to = "conc") |>
  dplyr::filter(!is.na(conc))

nca_dose <- nca_conc |>
  dplyr::distinct(id, Matrix) |>
  dplyr::mutate(time = ss_start, dose = 2000)

conc_obj <- PKNCA::PKNCAconc(nca_conc, conc ~ time | Matrix + id,
                             concu = "mg/L", timeu = "h")
dose_obj <- PKNCA::PKNCAdose(nca_dose, dose ~ time | Matrix + id,
                             doseu = "mg")

intervals <- data.frame(
  start = ss_start, end = ss_end,
  cmax = TRUE, tmax = TRUE, cmin = TRUE, auclast = TRUE, cav = TRUE
)

nca_res <- PKNCA::pk.nca(PKNCA::PKNCAdata(conc_obj, dose_obj, intervals = intervals))
nca_tab <- as.data.frame(nca_res)

nca_wide <- nca_tab |>
  dplyr::filter(PPTESTCD %in% c("cmax", "tmax", "cmin", "auclast", "cav")) |>
  tidyr::pivot_wider(id_cols = c(id, Matrix), names_from = PPTESTCD, values_from = PPORRES)

head(nca_wide)
#> # A tibble: 6 × 7
#>      id Matrix auclast  cmax  cmin  tmax   cav
#>   <int> <chr>    <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1     1 Milk      8.83 1.15  1.04   4.85 1.10 
#> 2     2 Milk     18.1  2.29  2.22   5.40 2.26 
#> 3     3 Milk      6.47 0.838 0.768  4.60 0.809
#> 4     4 Milk      1.27 0.194 0.110  3.55 0.158
#> 5     5 Milk      8.17 1.06  0.976  4.90 1.02 
#> 6     6 Milk      2.36 0.325 0.253  4.10 0.295
nca_wide |>
  dplyr::group_by(Matrix) |>
  dplyr::summarise(
    cmax = median(cmax), tmax = median(tmax), cmin = median(cmin),
    cav = median(cav), auclast = median(auclast), .groups = "drop"
  ) |>
  dplyr::rename(
    "Matrix"            = Matrix,
    "Cmax (mg/L)"       = cmax,
    "Tmax (h)"          = tmax,
    "Cmin (mg/L)"       = cmin,
    "Cavg (mg/L)"       = cav,
    "AUC0-tau (mg*h/L)" = auclast
  ) |>
  knitr::kable(digits = 3, caption = "Median steady-state NCA parameters at 2 g q8h, by matrix.")
Median steady-state NCA parameters at 2 g q8h, by matrix.
Matrix Cmax (mg/L) Tmax (h) Cmin (mg/L) Cavg (mg/L) AUC0-tau (mg*h/L)
Milk 0.894 4.70 0.785 0.845 6.763
Plasma 11.099 2.75 7.508 9.726 77.811

Baklouti 2026 reports no NCA table of its own – the paper’s only exposure summaries are the milk/plasma ratios and the relative infant dose of Table 4 – so the NCA is validated against the model’s own closed form rather than against a published NCA table.

The per-subject AUC-ratio identity

For each subject the two sides of the identity use the same drawn parameters, so the only difference is trapezoidal and integration error. That makes a tight bound the correct assertion here, unlike the cohort-versus-publication comparison that follows. Note that the prediction is each subject’s own k_central_milk / keff_milk, not the population value.

subject_k <- sim |>
  dplyr::group_by(id) |>
  dplyr::summarise(k_ratio = first(k_central_milk) / first(keff_milk), .groups = "drop")

ratio_chk <- nca_wide |>
  dplyr::select(id, Matrix, auclast) |>
  tidyr::pivot_wider(names_from = Matrix, values_from = auclast) |>
  dplyr::left_join(subject_k, by = "id") |>
  dplyr::mutate(
    observed = Milk / Plasma,
    pct_diff = 100 * (observed - k_ratio) / k_ratio
  )

summary(ratio_chk$pct_diff)
#>       Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
#> -0.0410995  0.0007687  0.0012342  0.0011221  0.0017082  0.0061861

stopifnot(
  # Solve against its own closed form: pure numerical error, so bound tightly.
  max(abs(ratio_chk$pct_diff)) < 0.5
)

Cohort ratio against the published Table 4

q_sim <- quantile(ratio_chk$observed, c(0.25, 0.5, 0.75))

data.frame(
  Statistic = c("First quartile", "Median", "Third quartile"),
  Simulated = sprintf("%.2f%%", 100 * q_sim),
  Published = c("6.6%", "8.5%", "11.1%")
) |>
  knitr::kable(caption = "Simulated milk/plasma AUC ratio vs Baklouti 2026 Table 4 (simulated, random breastfeeding).")
Simulated milk/plasma AUC ratio vs Baklouti 2026 Table 4 (simulated, random breastfeeding).
Statistic Simulated Published
First quartile 6.32% 6.6%
Median 8.69% 8.5%
Third quartile 11.36% 11.1%

stopifnot(
  # Centre: a mis-transcribed rate constant moves this by tens of percent.
  abs(100 * q_sim[["50%"]] - 8.5) < 1.5,
  # Envelope: robust quartiles rather than extremes, so the check does not
  # depend on which subjects land in the tails of a randomly drawn cohort.
  abs(100 * q_sim[["25%"]] - 6.6) < 2,
  abs(100 * q_sim[["75%"]] - 11.1) < 2.5
)

Validation 3 – milk/plasma concentration ratio

Table 4 also reports a milk/plasma concentration ratio – median 4.8%, quartiles 4.1-5.2%, range 3.3-5.4% – described as being sampled at simulated feeding times drawn across the day. For this model structure that quantity is tightly constrained by the AUC ratio, because the milk profile is a smoothed and delayed copy of the plasma profile rather than an independently shaped curve.

tv <- rxode2::rxSolve(rxode2::zeroRe(mod), ev, useLinCmt = FALSE) |> as.data.frame()
#> ℹ omega/sigma items treated as zero: 'etalka', 'etalvc', 'etalkel', 'etalk_central_milk', 'etalkeff_milk'
tv$ratio <- 100 * tv$Cmilk / tv$Cc

cohort_ratio <- sim |>
  dplyr::mutate(ratio = 100 * Cmilk / Cc) |>
  dplyr::filter(is.finite(ratio)) |>
  dplyr::pull(ratio)

data.frame(
  Source = c(
    "Typical subject, across the dosing interval",
    "Cohort (200 subjects, all interval times)",
    "Published simulated concentration ratio",
    "Published simulated AUC ratio",
    "Published MEASURED concentration ratio"
  ),
  Q1     = c(sprintf("%.1f%%", quantile(tv$ratio, 0.25)), sprintf("%.1f%%", quantile(cohort_ratio, 0.25)), "4.1%", "6.6%", "4.5%"),
  Median = c(sprintf("%.1f%%", median(tv$ratio)),         sprintf("%.1f%%", median(cohort_ratio)),         "4.8%", "8.5%", "6.0%"),
  Q3     = c(sprintf("%.1f%%", quantile(tv$ratio, 0.75)), sprintf("%.1f%%", quantile(cohort_ratio, 0.75)), "5.2%", "11.1%", "9.6%")
) |>
  knitr::kable(caption = "Milk/plasma concentration ratio produced by the packaged model, against the three ratios of Baklouti 2026 Table 4.")
Milk/plasma concentration ratio produced by the packaged model, against the three ratios of Baklouti 2026 Table 4.
Source Q1 Median Q3
Typical subject, across the dosing interval 7.6% 8.4% 9.5%
Cohort (200 subjects, all interval times) 6.4% 8.6% 11.7%
Published simulated concentration ratio 4.1% 4.8% 5.2%
Published simulated AUC ratio 6.6% 8.5% 11.1%
Published MEASURED concentration ratio 4.5% 6.0% 9.6%

The model’s concentration ratio sits at roughly 8.4-8.8%, i.e. it tracks the AUC ratio closely, and it falls inside the interquartile range of the paper’s own measured milk/plasma ratio (4.5-9.6%, median 6.0%). It does not reproduce the paper’s simulated concentration ratio of 4.8%, which is about half the model’s value.

That row appears to be internally inconsistent with the rest of Table 4 rather than a transcription error on our side. The simulated concentration ratio and the simulated AUC ratio are reported as coming from the same 10 000-draw simulation of the same model, yet for a structure in which milk is a linear first-order filter of plasma the two cannot differ by a factor of two: averaging Cmilk/Cc over the interval and dividing the two AUCs give nearly the same number, as the typical-subject row above shows (8.4% versus the closed-form 8.485%). The published concentration-ratio row is also implausibly tight – a full min-max of 3.3-5.4% across 10 000 draws, narrower than its own interquartile range for the AUC ratio, despite the two milk rate constants carrying 11% and 38% inter-individual variability. No assertion is made against that row; the AUC ratio is the reproducible gate.

# Averaging the concentration ratio over the interval and taking the ratio of
# the AUCs are two routes to the same number for this structure.
auc_tv <- c(
  milk   = sum(diff(tv$time) * (head(tv$Cmilk, -1) + tail(tv$Cmilk, -1)) / 2),
  plasma = sum(diff(tv$time) * (head(tv$Cc, -1)    + tail(tv$Cc, -1))    / 2)
)

data.frame(
  Route = c("Median of Cmilk/Cc over the interval", "AUC(milk) / AUC(plasma)", "Closed form kmilk / kmilk_e"),
  Value = sprintf("%.3f%%", c(median(tv$ratio), 100 * auc_tv[["milk"]] / auc_tv[["plasma"]], 100 * ratio_median))
) |>
  knitr::kable(caption = "Typical subject: the concentration ratio and the AUC ratio are the same quantity for this model.")
Typical subject: the concentration ratio and the AUC ratio are the same quantity for this model.
Route Value
Median of Cmilk/Cc over the interval 8.427%
AUC(milk) / AUC(plasma) 8.485%
Closed form kmilk / kmilk_e 8.485%

Validation 4 – relative infant dose

# Relative infant dose: the infant's weight-adjusted daily dose as a percentage
# of the mother's, assuming the standard 150 mL/kg/day milk intake
# (Methods section 2.4).
milk_intake <- 0.15                  # L/kg/day
maternal_wt <- 65                    # kg (Table 4 note)
maternal_dd <- 3 * 2000              # mg/day at 2 g q8h

rid <- nca_wide |>
  dplyr::filter(Matrix == "Milk") |>
  dplyr::mutate(
    infant_dose = cav * milk_intake,           # mg/kg/day
    maternal_pk = maternal_dd / maternal_wt,   # mg/kg/day
    rid_pct     = 100 * infant_dose / maternal_pk
  )

data.frame(
  Statistic = c("Median", "Third quartile", "Maximum"),
  Simulated = sprintf("%.3f%%", c(median(rid$rid_pct), quantile(rid$rid_pct, 0.75), max(rid$rid_pct))),
  Published = c("0.03%", "0.03%", "0.07%")
) |>
  knitr::kable(caption = "Relative infant dose at 2 g q8h vs Baklouti 2026 Table 4 (simulated, adult dosage).")
Relative infant dose at 2 g q8h vs Baklouti 2026 Table 4 (simulated, adult dosage).
Statistic Simulated Published
Median 0.137% 0.03%
Third quartile 0.191% 0.03%
Maximum 0.581% 0.07%

stopifnot(
  # The paper's clinical conclusion is that the RID sits far below the 2-3%
  # threshold at which breastfeeding is considered compatible. That conclusion
  # reproduces with a wide margin even though the exact published value does
  # not -- see Assumptions and deviations.
  median(rid$rid_pct) < 1,
  quantile(rid$rid_pct, 0.95) < 1
)

Computing the relative infant dose from the interval-average milk concentration gives roughly 0.1%, several times the published median of 0.03%, and it inherits the concentration-ratio discrepancy discussed above. Both figures are more than an order of magnitude below the 2-3% compatibility threshold, so the paper’s clinical conclusion – that amoxicillin is compatible with breastfeeding – is unaffected.

Assumptions and deviations

  • Milk volume. Vmilk is fixed equal to Vc (82.4 L). This is the authors’ own choice, made because milk volume was not identifiable and estimating it degraded the fit (Results section 3.2, p. 1837). It is not physiological – daily milk output averages about 2 L – and the Discussion defends it as avoiding over-parameterisation. Every milk concentration the model produces is therefore scaled by an apparent volume, not a real one. The milk/plasma ratio is nevertheless meaningful because the same volume divides both sides.

  • IIV on V/F. Methods section 2.3 states that “IIV was included in ka, ke, kmilk and kmilk_e”, omitting V/F, but Table 3 tabulates IIV V/F (se) 0.086 with RSE 47.7% and a 95% CI of 0.038-0.2. A row carrying an RSE and a confidence interval is an estimated component, so Table 3 was taken as authoritative and the eta on V/F was retained. The Methods sentence appears to be simply incomplete.

  • IIV scale. Table 3’s IIV rows are labelled (se) without stating whether they hold standard deviations or variances. They are encoded here as log-scale standard deviations, squared into rxode2’s variance parameterisation. Two independent printed quantities confirm this: the published AUC-ratio interquartile range (Validation 1) and the Discussion’s “CV = 37%” against IIV k a = 0.37.

  • Rate-constant parameterisation. The paper estimates ke and V/F as two separate parameters with an independent eta on each, so the model is encoded with lkel beside an explicit lvc rather than being reparameterised to lcl + lvc. The clearance form is algebraically equivalent only if etalcl = etalkel + etalvc, a correlated eta block the authors did not fit, so reparameterising would change the model.

  • Continuous milk elimination. keff_milk runs continuously, whereas milk is physically removed only at feeds. The authors flag this as the model’s main structural limitation and note that the drug amount in milk – and hence the relative infant dose – “would be higher if kmilk_e were set to zero between two consecutive feedings”. The packaged model reproduces the published structure rather than correcting it.

  • Simulated concentration ratio and relative infant dose are not reproducible. The model reproduces Table 4’s simulated milk/plasma AUC ratio exactly (median and both quartiles), but gives about 8.5% where Table 4 reports 4.8% for the simulated concentration ratio, and about 0.1% where Table 4 reports 0.03% for the relative infant dose. Validation 3 shows the concentration-ratio row is inconsistent with the AUC-ratio row from the same simulation given this model structure, and its published spread (3.3-5.4% across 10 000 draws) is far too narrow for parameters carrying 11% and 38% inter-individual variability. Methods section 2.4 does not state how milk volume is apportioned per feed or whether the milk compartment is emptied at a feed, so the published accumulation cannot be reconstructed from the printed method. The Discussion contains a further figure that reconciles with neither – a “maximal daily intake of amoxicillin from our model (0.022 mg/day)”, corresponding to a relative infant dose near 0.004%. No parameter was tuned to close any of these gaps; the model reproduces the published estimates and the published AUC ratio, and the differences are reported as found.

  • Foremilk sampling. All milk observations are foremilk collected without emptying the breast, which the authors state overestimates concentrations relative to whole-feed milk. The model inherits that bias, which is conservative for a safety assessment.

  • No covariates. None of maternal age, weight, height, breastfeeding exclusivity, eGFR or albumin, nor infant age, weight or height, was retained. The Discussion attributes the null renal result to the narrow eGFR spread in the cohort (CV 7.4%) rather than to the absence of a relationship. All screened covariates are documented in the model file’s covariatesDataExcluded.

  • No published NCA table. The paper reports no NCA summary, so the NCA section is validated against the model’s closed form rather than a published table.

Errata

No erratum, corrigendum or correction notice is recorded for this article. Europe PMC returns an empty commentCorrectionList for PMC13206287 as of 2026-09-02, and the article’s publisher page carries no correction notice.