Skip to contents

Model and source

Apomine is a synthetic bisphosphonate-ester anti-cancer agent given orally over a 30 to 2100 mg total daily dose range. Bonate 2004 pools four model-development studies (Studies 1, 2, 5, 6) of 19 healthy adult males and 19 male and female patients with advanced solid tumours and fits a two-compartment population PK model with a mixture first-order absorption (a dominant lagged-absorption Group 1 subpopulation, 97 percent; and a no-lag Group 2 subpopulation, 3 percent), dose-saturable relative bioavailability with a food effect, sigmoid Emax auto-induction of apparent oral clearance over elapsed time, and a fixed allometric weight effect on central volume of distribution. Cancer patients have lower baseline CL/F and lower central volume than healthy males; intercompartmental clearance and peripheral volume are common to both populations.

Population

The model-development dataset comprised 801 plasma apomine concentration measurements from 38 subjects across Studies 1, 2, 5 and 6 (Bonate 2004 Table 1 and Table 2). Studies 1 and 2 enrolled 19 healthy adult males (fasted, single or once-daily multiple-dose) in Dundee, Scotland; Studies 5 and 6 enrolled 19 adult male and female patients with advanced solid tumours (Study 5 once-weekly fasted, Study 6 multiple-dose twice-daily with food) at the Arizona Cancer Center and the Cancer Therapy and Research Center, San Antonio. Weight ranged 55-115 kg across the cohort; ages 18-78 years. Cancer patients received concomitant supportive-care medications but were excluded if on chemotherapy, immunotherapy, hormonal cancer therapy, radiation or CYP3A inhibitors. Two influential subjects (Study 1 subject 18 and Study 5 subject 11) identified by jack-knife principal-components analysis were removed before the final parameter estimates in Table 3 were obtained.

The same information is available programmatically via readModelDb("Bonate_2004_apomine")$population (call the function returned by readModelDb() and then inspect $population).

Source trace

Equation / parameter Value Source
Two-compartment PK with first-order absorption structural Methods “Base model development”; Results paragraph 1
lcl (CL0 in healthy males) 40.7 mL/h = 0.0407 L/h Table 3
lvc (TVV2 in healthy males at 75 kg) 12.3 L Table 3
e_cancer_cl = log(10.2 / 40.7) -1.384 Table 3 (CL0 cancer = 10.2 mL/h)
e_cancer_vc = log(7.11 / 12.3) -0.548 Table 3 (TVV2 cancer = 7.11 L)
Auto-induction: CL(t) = CL0 + CLmax x t^n / (t50^n + t^n) structural Table 3 “CL = CL0 + CLmax * Time^n / (t50^n + Time^n)”
lclmax (CLmax) 320 mL/h = 0.320 L/h Table 3
lt50 (t50) 46.4 h Table 3
lhill (induction shape parameter n) 6.40 Table 3
lq (intercompartmental clearance Q) 198 mL/h = 0.198 L/h Table 3
lvp (peripheral volume V3, typical-Vp subgroup) 1.83 L Table 3
e_wt_vc (allometric exponent on Vc, fixed) 1.0 Table 3 “Power term for weight on central compartment volume = 1.00 Fixed”
e_high_vp_vp = log(23.5) 3.157 Table 3 (peripheral compartment multiplier for Study 2 = 23.5)
Absorption mixture: Group 1 (97 %) lagged + faster ka; Group 2 (3 %) no-lag + slower ka structural Methods, equation (1.4); Results paragraph 1
lka1 (ka Group 1) 1.77 /h Table 3
ltlag (lag time Group 1) 0.821 h Table 3
lka2 (ka Group 2) 0.361 /h Table 3
Lag time Group 2 0 (fixed) Table 3
Mixing logit P1; P(Group 1) = 1 / (1 + exp(P1)) -3.47 -> P(Group 1) = 0.970 Table 3 (mixing fraction was 97% into group 1 and 3% into group 2)
Bioavailability: F1 = (1 - F1max x Dose / (Dose + D50)) x (1 + theta_food x FED) structural Methods, equation (1.1)
F1max (fixed) 1 Table 3 “F1max = 1 fixed”
ld50 (D50) 128 mg Table 3
e_food_f (theta_food) -0.360 Table 3
etalcl (BSV CL; omega^2 = log(CV^2 + 1)) log(0.68^2 + 1) = 0.4267 Table 3 BSV CL = 68%
etalvc (BSV Vc) log(0.30^2 + 1) = 0.08619 Table 3 BSV TVV2 = 30%
etalvp (BSV Vp) log(1.41^2 + 1) = 0.7945 Table 3 BSV V3 = 141%
etalt50 (BSV t50) log(0.88^2 + 1) = 0.5594 Table 3 BSV t50 = 88%
etalka (BSV ka, common to both groups) log(1.45^2 + 1) = 0.8126 Table 3 BSV ka = 145%
propSd (proportional residual SD) 0.11 Table 3 “Proportional error = 11”
addSd (additive residual SD, ug/mL) 0.168 Table 3 “Additive error = 0.168”

Virtual cohort

The original observed data are not publicly available. The figures below use typical-value forward simulations (rxode2::zeroRe) for canonical regimens that mirror Bonate 2004 Figures 7-8.

mod         <- readModelDb("Bonate_2004_apomine")
mod_typical <- rxode2::zeroRe(mod)
#> ℹ parameter labels from comments will be replaced by 'label()'

# Figure 8 replication. Bonate 2004 simulated 50 mg apomine once daily for 21
# days in 50 fasting healthy female subjects, with weight distributed at the
# female population mean. The original data did not include healthy females
# (Studies 1 and 2 were male-only) so the paper used the female weight mean
# from Studies 5 and 6 (~70 kg). Here we replicate the typical-value mean
# profile for that scenario; the multi-day AUC0-24h and Cmax-per-day
# trajectory is the relevant validation target.
events_50qd <- rxode2::et(amt = 50, cmt = "depot",
                          ii = 24, until = 21 * 24) |>
  rxode2::et(time = seq(0, 21 * 24, by = 0.5)) |>
  as.data.frame() |>
  dplyr::mutate(
    WT             = 70,
    DIS_CANCER     = 0,
    FED            = 0,
    MIX_LAGGED_ABS = 1,
    MIX_HIGH_VP    = 0
  )

Simulation

sim_50qd <- rxode2::rxSolve(mod_typical, events_50qd) |> as.data.frame()
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalt50', 'etalka'

Replicate published figures

Figure 8 –AUC(0,24 h) and Cmax over 21 days of 50 mg qd dosing

Bonate 2004 reports that with continued once-daily 50 mg dosing in healthy female subjects, both AUC(0,24 h) and Cmax increase over the first week of administration, then decrease and reach steady state after about 14 days. Day 14 exposure is approximately twice that of Day 1 (Bonate 2004 Discussion).

daily_summary <- sim_50qd |>
  dplyr::mutate(day = floor(time / 24) + 1) |>
  dplyr::filter(day <= 21) |>
  dplyr::group_by(day) |>
  dplyr::summarise(
    AUC24h_typ = sum(diff(time) * (head(Cc, -1) + tail(Cc, -1)) / 2),
    Cmax_typ   = max(Cc, na.rm = TRUE),
    .groups    = "drop"
  )

daily_long <- daily_summary |>
  tidyr::pivot_longer(c(AUC24h_typ, Cmax_typ),
                      names_to = "metric", values_to = "value") |>
  dplyr::mutate(
    metric_label = factor(
      metric,
      levels = c("AUC24h_typ", "Cmax_typ"),
      labels = c("AUC(0,24 h) (h * ug/mL)", "Cmax (ug/mL)")
    )
  )

ggplot(daily_long, aes(day, value)) +
  geom_line() +
  geom_point() +
  facet_wrap(~metric_label, scales = "free_y", ncol = 1) +
  labs(
    x       = "Day of drug administration",
    y       = NULL,
    caption = "Replicates Bonate 2004 Figure 8 (mean line)."
  ) +
  theme_bw()
Replicates Bonate 2004 Figure 8: typical-value 24-h AUC and Cmax in fasting healthy females over 21 days of 50 mg apomine once daily.

Replicates Bonate 2004 Figure 8: typical-value 24-h AUC and Cmax in fasting healthy females over 21 days of 50 mg apomine once daily.

The typical-value 24-h AUC and Cmax trajectories show the characteristic rise over the first week, the auto-induction-driven decline, and steady-state attainment near day 14, with day-14 exposures roughly double the day-1 values (matching the paper’s narrative).

Figure 7 –Apparent terminal half-life over time in healthy vs cancer

Bonate 2004 Figure 7 plots the lambda-1 and lambda-z macroconstant half-lives as a function of day of drug administration. At steady state the least-squares mean lambda-1 half-life was 5.5 h in cancer patients and 4.5 h in healthy volunteers; the least-squares mean lambda-z half-life was 41 h in cancer patients and 32 h in healthy volunteers (Bonate 2004 Results paragraph 6).

# Two cohorts: typical healthy male (DIS_CANCER = 0) and typical cancer
# patient (DIS_CANCER = 1), both 75 kg, fasted, Group 1 absorption. Compute
# day-stratified macroconstant half-lives at the SS time point (day 21).
ss_events <- function(dis_cancer) {
  rxode2::et(amt = 50, cmt = "depot",
             ii = 24, until = 21 * 24) |>
    rxode2::et(time = seq(0, 21 * 24, by = 0.5)) |>
    as.data.frame() |>
    dplyr::mutate(
      WT             = 75,
      DIS_CANCER     = dis_cancer,
      FED            = 0,
      MIX_LAGGED_ABS = 1,
      MIX_HIGH_VP    = 0
    )
}

# Compute macroconstants analytically at any time t for a two-compartment
# model with the published induced clearance. Returns t1/2-alpha (lambda-1)
# and t1/2-beta (lambda-z) in hours.
two_cmt_half_lives <- function(cl, vc, q, vp) {
  kel <- cl / vc
  k12 <- q  / vc
  k21 <- q  / vp
  s   <- kel + k12 + k21
  p   <- kel * k21
  disc <- s^2 - 4 * p
  lambda1 <- (s + sqrt(disc)) / 2
  lambda2 <- (s - sqrt(disc)) / 2
  c(t_half_alpha = log(2) / lambda1, t_half_beta = log(2) / lambda2)
}

# CL(t) in each population over 21 days
days  <- 1:21
hours <- days * 24
hill  <- 6.40
t50   <- 46.4
clmax <- 0.320

cl0_healthy <- 0.0407
vc_healthy  <- 12.3
cl0_cancer  <- 0.0102
vc_cancer   <- 7.11
q_common    <- 0.198
vp_common   <- 1.83

induction <- hours^hill / (t50^hill + hours^hill)

hl_long <- dplyr::bind_rows(
  tibble::tibble(
    day        = days,
    population = "Healthy males",
    t1_2_alpha = vapply(induction, function(i) {
      cl_t <- cl0_healthy + clmax * i
      two_cmt_half_lives(cl_t, vc_healthy, q_common, vp_common)[1]
    }, numeric(1)),
    t1_2_beta  = vapply(induction, function(i) {
      cl_t <- cl0_healthy + clmax * i
      two_cmt_half_lives(cl_t, vc_healthy, q_common, vp_common)[2]
    }, numeric(1))
  ),
  tibble::tibble(
    day        = days,
    population = "Cancer patients",
    t1_2_alpha = vapply(induction, function(i) {
      cl_t <- cl0_cancer + clmax * i
      two_cmt_half_lives(cl_t, vc_cancer, q_common, vp_common)[1]
    }, numeric(1)),
    t1_2_beta  = vapply(induction, function(i) {
      cl_t <- cl0_cancer + clmax * i
      two_cmt_half_lives(cl_t, vc_cancer, q_common, vp_common)[2]
    }, numeric(1))
  )
) |>
  tidyr::pivot_longer(c(t1_2_alpha, t1_2_beta),
                      names_to = "macroconstant", values_to = "t_half") |>
  dplyr::mutate(
    macroconstant = factor(
      macroconstant,
      levels = c("t1_2_alpha", "t1_2_beta"),
      labels = c("lambda-1 half-life (h)", "lambda-z half-life (h)")
    )
  )

ggplot(hl_long, aes(day, t_half, colour = population)) +
  geom_line() +
  geom_point() +
  facet_wrap(~macroconstant, scales = "free_y", ncol = 1) +
  labs(
    x       = "Day of drug administration",
    y       = NULL,
    colour  = NULL,
    caption = "Replicates Bonate 2004 Figure 7 (typical-value lines for healthy vs cancer)."
  ) +
  theme_bw() +
  theme(legend.position = "top")

At day 21 (steady state), the computed typical-value half-lives are:

hl_long |>
  dplyr::filter(day == 21) |>
  dplyr::select(population, macroconstant, t_half) |>
  tidyr::pivot_wider(names_from = macroconstant, values_from = t_half) |>
  knitr::kable(digits = 2, caption = "Day-21 typical-value half-lives.")
Day-21 typical-value half-lives.
population lambda-1 half-life (h) lambda-z half-life (h)
Healthy males 5.37 28.19
Cancer patients 4.66 20.51

Comparison with Bonate 2004 Results paragraph 6 (least-squares means at steady state): lambda-1 half-life 4.5 h (healthy) and 5.5 h (cancer); lambda-z half-life 32 h (healthy) and 41 h (cancer). The simulated typical-value values agree to within rounding.

PKNCA validation

Apomine reaches steady state after roughly two weeks of once-daily dosing. The table below computes Cmax, AUC over 24 h, and the apparent terminal half-life on day 21 (the steady-state interval) for a typical healthy male and a typical cancer patient.

sim_typ_healthy <- rxode2::rxSolve(mod_typical, ss_events(0)) |>
  as.data.frame() |>
  dplyr::mutate(id_label = 1L,
                treatment = "Typical healthy male, 50 mg qd")
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalt50', 'etalka'
sim_typ_cancer  <- rxode2::rxSolve(mod_typical, ss_events(1)) |>
  as.data.frame() |>
  dplyr::mutate(id_label = 2L,
                treatment = "Typical cancer patient, 50 mg qd")
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalvc', 'etalvp', 'etalt50', 'etalka'

sim_typ <- dplyr::bind_rows(sim_typ_healthy, sim_typ_cancer)

# PKNCA over the final dosing interval (day 20 -> day 21).
ss_start <- 20 * 24
ss_end   <- 21 * 24

sim_nca <- sim_typ |>
  dplyr::filter(time >= ss_start, time <= ss_end + 24, !is.na(Cc)) |>
  dplyr::transmute(id = id_label, time, Cc, treatment)

# Build a PKNCA dose data frame directly: one row per subject at the
# day-20 dose time. The rxode2 event table uses addl/ii encoding which
# compresses 21 doses into one row, so the dose times for PKNCA are
# constructed here from the regimen description rather than filtered
# back out of the event table.
dose_df <- tibble::tibble(
  id        = c(1L, 2L),
  time      = ss_start,
  amt       = 50,
  treatment = c("Typical healthy male, 50 mg qd",
                "Typical cancer patient, 50 mg qd")
)

conc_obj <- PKNCA::PKNCAconc(sim_nca, Cc ~ time | treatment + id,
                             concu = "ug/mL", timeu = "h")
dose_obj <- PKNCA::PKNCAdose(dose_df, amt ~ time | treatment + id,
                             doseu = "mg")

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

nca_res <- PKNCA::pk.nca(PKNCA::PKNCAdata(conc_obj, dose_obj,
                                          intervals = intervals))
knitr::kable(as.data.frame(summary(nca_res)),
             caption = "Day-21 steady-state NCA: typical-value simulation by patient population.")
Day-21 steady-state NCA: typical-value simulation by patient population.
Interval Start Interval End treatment N AUClast (h*ug/mL) Cmax (ug/mL) Tmax (h) Half-life (h)
480 504 Typical cancer patient, 50 mg qd 1 109 6.97 2.50 18.5
480 504 Typical healthy male, 50 mg qd 1 99.7 5.48 2.50 26.2

PKNCA’s terminal half-life estimate uses the lambda-z arm of the two-compartment disposition; the values are consistent with the analytic macroconstant computations in the Figure 7 table.

Assumptions and deviations

  • Inter-occasion variability omitted. Bonate 2004 Table 3 reports 18 % inter-occasion variability on both CL and central volume. The model file omits IOV because the occasion definition (one occasion per sampling day in the source paper) is study-design-specific and would require the user to supply an occasion-flag column at simulation time. The same omission is the standard nlmixr2lib practice (cf. Bienczak_2016_nevirapine, Svensson_2016_rifampicin); the typical-value forward simulations in this vignette are unaffected.

  • Mixture-absorption class selection via covariate. The source NONMEM model used a $MIXTURE block with two latent classes (Group 1 = lagged absorption, 97 %; Group 2 = no-lag absorption, 3 %). The packaged model exposes the class assignment as the binary covariate MIX_LAGGED_ABS with reference category 0 (Group 2). For typical-value reproduction of the dominant phenotype set MIX_LAGGED_ABS = 1; for population simulation, draw MIX_LAGGED_ABS ~ Bernoulli(0.970) per subject. The same indicator-covariate pattern is used by Tsuji_2017_linezolid (MIX_PDI) and Schindler_2017_imatinib (MIX_LARGE_BASE).

  • High-Vp subgroup as a binary indicator. Bonate 2004 Results identified four healthy-male multiple-dose subjects in Study 2 with peripheral volume of distribution roughly 23.5-fold higher than the rest of the cohort, modelled as a multiplicative shift Vp = TVV3 * theta_Study2. The packaged model exposes this as the binary covariate MIX_HIGH_VP with reference category 0 (typical-Vp majority); the paper notes that simulations with and without this multiplier showed minimal differences in concentration-time profiles.

  • Residual-error form. The paper reports Y = F * exp(eps1) + eps2 (exponential-proportional plus additive). For the cohort’s CV of 11 % this is well-approximated by the nlmixr2 prop(propSd) + add(addSd) idiom (propSd = 0.11, addSd = 0.168 ug/mL); the deviation at low concentrations is < 1 % of the additive floor.

  • Auto-induction in single-dose simulations. Bonate 2004 held CL time-invariant for the single-dose Study 1 fit during estimation. The packaged model retains the time-dependent CL formula CL(t) = CL0 + CLmax * t^hill / (t50^hill + t^hill) for all simulations. With the published t50 = 46.4 h and hill = 6.40, induction at t = 24 h is only ~1.4 % of CLmax, so the single-dose forward simulation is not materially affected.

  • Fraction-female reproduction. Bonate 2004 Figure 8 simulated healthy female subjects, but the model-development cohort included healthy females only in Studies 5 and 6 (cancer patients). The paper used the female weight mean from those studies (~70 kg); the same weight is used here. No sex-specific CL/F or Vc/F effect was retained in the final model (Table 3 sex was tested and not retained).