Skip to contents

Model and source

  • Citation: Wang Y, Marier JF, Lavigne J, Kassir N, Martin P. Population Pharmacokinetics and Pharmacodynamics of Ontamalimab (SHP647), a Fully Human Monoclonal Antibody Against Mucosal Addressin Cell Adhesion Molecule-1 (MAdCAM-1), in Patients With Ulcerative Colitis or Crohn’s Disease. J Clin Pharmacol. 2020;60(7):903-914. doi:10.1002/jcph.1590.
  • Description: Two-compartment population PK model for ontamalimab (SHP647), a fully human IgG2 anti-MAdCAM-1 monoclonal antibody, in adults with moderate-to-severe ulcerative colitis or Crohn’s disease (Wang 2020), with first-order SC absorption, absorption lag time, parallel linear and Michaelis-Menten elimination from the central compartment, and allometric weight scaling on CL, Vc, Q, Vp, and Vmax.
  • Article: J Clin Pharmacol. 2020;60(7):903-914 (open access via PMC7383906)

Population

Wang 2020 pooled two phase 2 induction studies — OPERA (NCT01276509) in Crohn’s disease (CD) and TURANDOT (NCT01620255) in ulcerative colitis (UC) — into a population PK dataset of 440 adults with moderate-to-severe IBD who had failed or were intolerant to immunosuppressants and/or anti-TNF agents. Patients received 3 SC doses of ontamalimab (7.5, 22.5, 75, or 225 mg, with TURANDOT also including a 7.5 mg arm) at days 1, 28, and 56 of a 12-week treatment period; 2138 ontamalimab concentration measurements entered the analysis (9.4% below the 10 ng/mL LLOQ were treated as missing).

Baseline demographics from Table 1: median age 37 years (range 18-68), 51.1% female, median body weight 68.8 kg (range 35.6-155), 86.1% White / 10.0% Asian / 3.9% other, median baseline serum albumin 39 g/L (range 23-49), median baseline CRP 0.837 mg/dL (range 0.01-18). Disease split: 191 (43.4%) CD and 249 (56.6%) UC.

The same information is available programmatically via readModelDb("Wang_2020_ontamalimab")$population.

Source trace

Every structural parameter, covariate effect, IIV element, and residual-error term below is taken from Wang 2020 Table 2. The reference covariate values (Table 2 footnote) are a 70 kg patient with UC or CD, baseline albumin 39 g/L, and baseline CRP 0.837 mg/dL.

Equation / parameter Value (paper unit) Value (model unit, time = day, conc = mg/L) Source location
lka (Ka) 0.0187 1/h log(0.0187 * 24) 1/day Table 2, Ka row
ltlag (Lag) 2.61 h log(2.61 / 24) day Table 2, Lag row
lcl (CL/F) 0.0127 L/h log(0.0127 * 24) L/day Table 2, CL/F row
lvc (Vc/F) 6.53 L log(6.53) L Table 2, Vc/F row
lq (CLd/F) 0.000345 L/h log(0.000345 * 24) L/day Table 2, CLd/F row
lvp (Vp/F) 0.0216 L log(0.0216) L Table 2, Vp/F row
lvmax (Vmax/F) 5.87 µg/h log(5.87 * 24 / 1000) mg/day Table 2, Vmax/F row
lkm (Km) 19.0 ng/mL log(19.0 / 1000) mg/L Table 2, Km row
e_wt_cl (WT/70 exponent on CL/F) 0.0034 0.0034 Table 2, CL/F covariate equation
e_wt_vc (WT/70 exponent on Vc/F) 0.635 0.635 Table 2, Vc/F covariate equation
e_wt_q (WT/70 exponent on Q/F) 0.0034 0.0034 Table 2, CLd/F covariate equation
e_wt_vp (WT/70 exponent on Vp/F) 0.635 0.635 Table 2, Vp/F covariate equation
e_wt_vmax (WT/70 exponent on Vmax/F) 1.89 1.89 Table 2, Vmax/F covariate equation
e_alb_cl (ALB/39 exponent on CL/F) -0.889 -0.889 Table 2, CL/F covariate equation
e_crp_cl (CRP/0.837 exponent on CL/F) 0.147 0.147 Table 2, CL/F covariate equation
var(etalka) log(0.618^2 + 1) = 0.3232 same Table 2: Ka BSV 61.8% CV
var(etalcl) log(0.546^2 + 1) = 0.2611 same Table 2: CL/F BSV 54.6% CV
var(etalvc) log(0.410^2 + 1) = 0.1554 same Table 2: Vc/F BSV 41.0% CV
addSd 166 ng/mL 0.166 mg/L Table 2: additive residual
propSd 19.6% 0.196 Table 2: proportional residual
Structure (2-cmt + first-order SC + lag + linear + MM elimination) n/a n/a Methods “Population PK Analysis” and Table 2

Parameterization notes

  • Parallel linear and Michaelis-Menten elimination. Wang 2020 parameterizes total clearance as the sum of first-order linear apparent clearance (CL/F) and saturable Michaelis-Menten elimination with apparent parameters Vmax/F (mass per time) and Km. The ODE is implemented explicitly because linCmt() does not support nonlinear elimination.
  • CV% to log-normal variance. Wang 2020 Table 2 reports between-subject variability as CV% on the linear-parameter scale. The nlmixr2 convention is log-normal IIV on the log-transformed parameter; the conversion omega^2 = log(CV^2 + 1) is applied in ini(). The paper does not report off-diagonal correlations, so the IIVs on Ka, CL/F, and Vc/F are coded as independent.
  • Unit conversions. The paper reports rates in 1/h, clearances in L/h, Vmax/F in µg/h, Km in ng/mL, lag in h, and concentrations in ng/mL. The model uses the nlmixr2lib convention (time = day, dose = mg, concentration = mg/L). Conversions: 1/h × 24 = 1/day, L/h × 24 = L/day, h / 24 = day, µg/h × 24 / 1000 = mg/day, ng/mL / 1000 = mg/L.
  • Allometric weight scaling. Body weight is applied as a power effect to five parameters (CL, Vc, Q, Vp, Vmax). Note the small CL and Q exponents (~0.003) and the larger Vmax exponent (1.89); these are the estimated values in Table 2 rather than fixed allometric exponents.
  • CRP unit (mg/dL, not the canonical mg/L). Wang 2020 reports CRP in mg/dL with reference 0.837 mg/dL (overall median). The canonical CRP covariate column in nlmixr2lib is documented in mg/L, but per-model units are honored: covariateData[[CRP]]$units = "mg/dL" here. Users supplying CRP in mg/L should divide by 10 before passing the column to this model (or use CRP_mgL / 10 directly).
  • Vp/F is small (0.0216 L). The published peripheral apparent volume is small relative to Vc/F (6.53 L). The corresponding alpha-distribution half-life is approximately 1.8 days at the reference covariate values while the apparent terminal half-life is approximately 14.9 days, both consistent with the paper’s reported dose-dependent half-lives of 12.3-18.6 days at the 22.5-225 mg Q4W dose levels (Methods “Population PK Analysis”). The value was verified against the original PMC XML to rule out a parsing artifact.
  • Lag time. First-order SC absorption with a 2.61 h absorption lag is applied via alag(depot).

Virtual cohort

The simulations below use a virtual cohort whose covariate distributions approximate the Wang 2020 Table 1 demographics. No subject-level observed data were released with the paper.

set.seed(20260425)
n_subj <- 200

# Body weight: log-normal with median 68.8 kg and a spread that matches
# the 95% CI 45-116 kg in Table 1; truncated to the observed range.
# Albumin and CRP: log-normal with parameters set so the simulated medians
# and 95% CI roughly match Table 1 (ALB median 39 g/L, 95% CI 29-47;
# CRP median 0.837 mg/dL, 95% CI 0.030-8.83).
cohort <- tibble::tibble(
  id  = seq_len(n_subj),
  WT  = pmin(pmax(rlnorm(n_subj, log(68.8), 0.24),  35),  155),
  ALB = pmin(pmax(rlnorm(n_subj, log(39),  0.12),   23),  49),
  CRP = pmin(pmax(rlnorm(n_subj, log(0.837), 1.18), 0.01), 18)
)

The dosing simulation reproduces the Wang 2020 phase 2 induction regimen: 3 SC doses Q4W on days 1, 28, and 56, with observations through week 12 (day 84). Five dose arms (7.5, 22.5, 75, 150, 225 mg Q4W) are simulated to match Table 3 of the paper.

tau    <- 28L                       # Q4W dosing interval (days)
n_dose <- 3L                        # day 1, day 29, day 57 in 1-indexed; here day 0, 28, 56
dose_days <- seq(0, tau * (n_dose - 1), by = tau)
end_day   <- tau * n_dose            # day 84 = end of week 12

build_events <- function(cohort, dose_amt, treatment) {
  ev_dose <- cohort |>
    tidyr::crossing(time = dose_days) |>
    dplyr::mutate(amt = dose_amt, cmt = "depot", evid = 1L,
                  treatment = treatment)
  obs_times <- sort(unique(c(
    seq(0, end_day, by = 1),                    # daily through week 12
    dose_days + 0.25, dose_days + 1, dose_days + 3, dose_days + 7
  )))
  ev_obs <- cohort |>
    tidyr::crossing(time = obs_times) |>
    dplyr::mutate(amt = 0, cmt = NA_character_, evid = 0L,
                  treatment = treatment)
  dplyr::bind_rows(ev_dose, ev_obs) |>
    dplyr::arrange(id, time, dplyr::desc(evid)) |>
    dplyr::select(id, time, amt, cmt, evid, treatment, WT, ALB, CRP)
}

doses <- c("7p5mg_Q4W"   = 7.5,
           "22p5mg_Q4W"  = 22.5,
           "75mg_Q4W"    = 75,
           "150mg_Q4W"   = 150,
           "225mg_Q4W"   = 225)

events <- dplyr::bind_rows(
  lapply(seq_along(doses), function(i) {
    build_events(cohort, doses[[i]], names(doses)[i])
  })
)

Simulation

mod <- rxode2::rxode2(readModelDb("Wang_2020_ontamalimab"))
keep_cols <- c("WT", "ALB", "CRP", "treatment")

sim <- lapply(split(events, events$treatment), function(ev) {
  out <- rxode2::rxSolve(mod, events = ev, keep = keep_cols)
  as.data.frame(out)
}) |> dplyr::bind_rows()

Replicate published figures

Concentration-time profile by dose level

Wang 2020 Figure 1 (top panel) shows the observed individual concentration- time profiles of ontamalimab over the 12-week treatment period. The block below reproduces the dose-dependent shape with simulated 5th/50th/95th percentile bands across all five dose arms.

vpc <- sim |>
  dplyr::filter(!is.na(Cc), time > 0, time <= end_day) |>
  dplyr::group_by(treatment, time) |>
  dplyr::summarise(
    Q05 = quantile(Cc, 0.05, na.rm = TRUE),
    Q50 = quantile(Cc, 0.50, na.rm = TRUE),
    Q95 = quantile(Cc, 0.95, na.rm = TRUE),
    .groups = "drop"
  ) |>
  dplyr::mutate(treatment = factor(treatment,
    levels = c("7p5mg_Q4W", "22p5mg_Q4W", "75mg_Q4W", "150mg_Q4W", "225mg_Q4W"),
    labels = c("7.5 mg", "22.5 mg", "75 mg", "150 mg", "225 mg")
  ))

ggplot(vpc, aes(time, Q50 * 1000, colour = treatment, fill = treatment)) +
  geom_ribbon(aes(ymin = Q05 * 1000, ymax = Q95 * 1000), alpha = 0.15, colour = NA) +
  geom_line(linewidth = 0.7) +
  scale_y_log10() +
  labs(
    x = "Time (days)",
    y = "Ontamalimab Cc (ng/mL)",
    title = "Simulated 5-50-95 percentile profiles by Q4W dose level",
    caption = "Virtual IBD cohort (N = 200); 3 SC doses Q4W on days 0, 28, 56; observations through week 12."
  ) +
  theme_minimal()

PKNCA validation

Non-compartmental analysis is computed over the dose-3 interval (day 56 to day 84 = week 12), matching the window in which Wang 2020 Table 3 reports the geometric-mean Cave, Cmax, and Cmin “at week 12”. Concentrations are expressed in ng/mL to match the published table.

ss_start <- tau * (n_dose - 1)    # day 56
ss_end   <- ss_start + tau        # day 84

nca_conc <- sim |>
  dplyr::filter(time >= ss_start, time <= ss_end, !is.na(Cc)) |>
  dplyr::mutate(time_nom = time - ss_start, Cc_ng = Cc * 1000) |>
  dplyr::select(id, time = time_nom, Cc = Cc_ng, treatment)

nca_dose <- dplyr::bind_rows(
  lapply(seq_along(doses), function(i) {
    cohort |> dplyr::mutate(time = 0, amt = doses[[i]], treatment = names(doses)[i])
  })
) |>
  dplyr::select(id, time, amt, treatment)

conc_obj <- PKNCA::PKNCAconc(nca_conc, Cc ~ time | treatment + id)
dose_obj <- PKNCA::PKNCAdose(nca_dose, amt ~ time | treatment + id)

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

nca_res <- PKNCA::pk.nca(PKNCA::PKNCAdata(conc_obj, dose_obj, intervals = intervals))
summary(nca_res)
#>  start end  treatment   N       auclast         cmax          cmin
#>      0  28  150mg_Q4W 200 432000 [50.7] 23500 [35.8]    5880 [197]
#>      0  28  225mg_Q4W 200 688000 [53.3] 37200 [39.1]    9330 [249]
#>      0  28 22p5mg_Q4W 200  55600 [52.8]  3220 [36.8]    325 [4710]
#>      0  28   75mg_Q4W 200 206000 [48.7] 11400 [37.0]    2310 [527]
#>      0  28  7p5mg_Q4W 200  11600 [58.2]   836 [46.7] 3.56 [982000]
#>               tmax          cav
#>  5.00 [2.00, 12.0] 15400 [50.7]
#>  5.00 [2.00, 14.0] 24600 [53.3]
#>  5.00 [2.00, 11.0]  1980 [52.8]
#>  5.00 [2.00, 11.0]  7360 [48.7]
#>  5.00 [2.00, 11.0]   415 [58.2]
#> 
#> Caption: auclast, cmax, cmin, cav: geometric mean and geometric coefficient of variation; tmax: median and range; N: number of subjects

Comparison against published Table 3 exposures

Wang 2020 Table 3 reports the geometric-mean Cave, Cmax, and Cmin “at week 12” for the 5 simulated Q4W dose levels. The block below extracts the geometric mean of the simulated dose-3 cycle across the 200 subjects in the virtual cohort and lays it side-by-side with the published values.

gmean <- function(x) exp(mean(log(pmax(x, .Machine$double.eps))))

per_subject <- nca_conc |>
  dplyr::group_by(treatment, id) |>
  dplyr::summarise(
    Cmax = max(Cc),
    Cmin = Cc[which.max(time)],
    Cave = sum(diff(time) * (head(Cc, -1) + tail(Cc, -1)) / 2) / tau,
    .groups = "drop"
  )

sim_summary <- per_subject |>
  dplyr::group_by(treatment) |>
  dplyr::summarise(
    Cmax_sim = gmean(Cmax),
    Cmin_sim = gmean(pmax(Cmin, 0.001)),
    Cave_sim = gmean(Cave),
    .groups = "drop"
  )

# Wang 2020 Table 3 published geometric means at week 12 (ng/mL)
published <- tibble::tribble(
  ~treatment,    ~Dose, ~Cave_pub, ~Cmax_pub, ~Cmin_pub,
  "7p5mg_Q4W",     7.5,       461,       986,      2.13,
  "22p5mg_Q4W",   22.5,      1930,      3300,       304,
  "75mg_Q4W",       75,      8160,     12000,      3670,
  "150mg_Q4W",     150,     11500,     17400,      5190,
  "225mg_Q4W",     225,     27700,     38100,     14600
)

comparison <- published |>
  dplyr::left_join(sim_summary, by = "treatment") |>
  dplyr::mutate(
    Cave_pct_diff = 100 * (Cave_sim - Cave_pub) / Cave_pub,
    Cmax_pct_diff = 100 * (Cmax_sim - Cmax_pub) / Cmax_pub,
    Cmin_pct_diff = 100 * (Cmin_sim - Cmin_pub) / Cmin_pub
  ) |>
  dplyr::select(treatment, Dose,
                Cave_pub, Cave_sim, Cave_pct_diff,
                Cmax_pub, Cmax_sim, Cmax_pct_diff,
                Cmin_pub, Cmin_sim, Cmin_pct_diff)

arms_over_20 <- function(pct_diff) {
  d <- comparison$Dose[abs(pct_diff) > 20]
  if (length(d) == 0) "none" else paste0(paste(d, collapse = ", "), " mg")
}

knitr::kable(comparison, digits = c(0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1),
  caption = paste0("Geometric-mean exposures at week 12 (dose-3 cycle, ng/mL) ",
                   "vs. Wang 2020 Table 3. Arms differing from the published ",
                   "value by more than 20%: Cave ",
                   arms_over_20(comparison$Cave_pct_diff), "; Cmax ",
                   arms_over_20(comparison$Cmax_pct_diff), "; Cmin ",
                   arms_over_20(comparison$Cmin_pct_diff), ". Cmin is the ",
                   "most sensitive metric because the week-12 trough is ",
                   "governed by the saturable elimination; see Assumptions ",
                   "and deviations."))
Geometric-mean exposures at week 12 (dose-3 cycle, ng/mL) vs. Wang 2020 Table 3. Arms differing from the published value by more than 20%: Cave 150 mg; Cmax 150 mg; Cmin 7.5, 75, 150, 225 mg. Cmin is the most sensitive metric because the week-12 trough is governed by the saturable elimination; see Assumptions and deviations.
treatment Dose Cave_pub Cave_sim Cave_pct_diff Cmax_pub Cmax_sim Cmax_pct_diff Cmin_pub Cmin_sim Cmin_pct_diff
7p5mg_Q4W 7.5 461 415 -10.0 986 836 -15.2 2.1 3.8 76.8
22p5mg_Q4W 22.5 1930 1985 2.9 3300 3224 -2.3 304.0 353.6 16.3
75mg_Q4W 75.0 8160 7360 -9.8 12000 11394 -5.0 3670.0 2484.8 -32.3
150mg_Q4W 150.0 11500 15446 34.3 17400 23547 35.3 5190.0 6375.6 22.8
225mg_Q4W 225.0 27700 24567 -11.3 38100 37183 -2.4 14600.0 10107.2 -30.8

Assumptions and deviations

  • Cohort covariate distributions are approximated. The virtual cohort draws WT, ALB, and CRP from log-normal distributions whose medians and 95% intervals approximate Table 1 of the paper, but no subject-level data were released. The actual study cohort had a mixture of CD and UC patients with different CRP distributions (CD median 1.79 mg/dL vs UC 0.407 mg/dL); a single pooled log-normal is used here.
  • No correlation between WT, ALB, and CRP in the virtual cohort. The paper does not report a covariate covariance matrix; the three covariates are simulated independently. Sicker patients tend to have lower albumin and higher CRP simultaneously, so this assumption likely understates the joint covariate effect on CL.
  • IIV correlation matrix not reported. Wang 2020 Table 2 reports marginal BSV% but no off-diagonal correlations between Ka, CL/F, and Vc/F etas. The IIVs are coded as independent. If correlated etas were used in the original NONMEM run, simulated variability bands at the extremes will be slightly mis-shaped.
  • Vp/F = 0.0216 L is unusually small. The paper reports a very small apparent peripheral volume. The value was verified against the original PMC XML to confirm it is not a parsing artifact. The corresponding alpha-distribution half-life is approximately 1.8 days at reference covariate values; the terminal apparent half-life is approximately 14.9 days, both consistent with the paper’s narrative (12.3-18.6 days dose-dependent half-life). Users who need a model that approximates the half-life behaviour but with a more typical peripheral volume should use a different reference paper.
  • CRP unit is mg/dL, not mg/L. Wang 2020 expresses CRP in mg/dL throughout (Table 1 medians, Table 2 reference). The covariate column is taken as mg/dL with reference 0.837 mg/dL. If a user has CRP in mg/L (the canonical nlmixr2lib unit), they must divide by 10 before passing it to this model.
  • Cmin sensitivity. The week-12 trough is governed by the saturable MM elimination, so simulated Cmin is highly sensitive to the cohort weight, albumin, and CRP distributions (Vmax/F scales with (WT/70)^1.89) and to the difference between a geometric mean over a heterogeneous cohort and a typical-patient value. Cmin differs from Table 3 by more than 20% in the 7.5, 75, 150, 225 mg arms, whereas Cave and Cmax exceed a 20% difference only in the 150 mg (Cave) and 150 mg (Cmax) arms (see the next bullet). These differences reflect the cohort approximation rather than a structural problem with the model.
  • Published 150 mg row. Wang 2020 Table 3 reports Cave 11500 / Cmax 17400 / Cmin 5190 ng/mL at 150 mg Q4W, which is lower per mg of dose than both the 75 mg row (8160 / 12000 / 3670) and the 225 mg row (27700 / 38100 / 14600). With saturable elimination, dose-normalized exposure rises monotonically with dose, so the model cannot reproduce that dip: the simulated 150 mg exposures sit 34% (Cave) and 35% (Cmax) above the published values.
  • No PK/PD model. Wang 2020 also fits a linear PK/PD model linking log-ontamalimab to log-MAdCAM-1 concentration. This nlmixr2lib model is PK only; the PK/PD parameters (E0 = 5.48, Slope = -0.375 on log scale, Hill <1 in the Imax model) are documented in the paper for users who wish to extend the model.
  • Population mixes UC and CD. Disease status was tested as a covariate on CL/F and Vc/F and was not statistically significant; the final model pools both indications. The single covariate dataset and reference subject reflect this pooling.