Eplontersen (Diep 2022)
Source:vignettes/articles/Diep_2022_eplontersen.Rmd
Diep_2022_eplontersen.Rmd
library(nlmixr2lib)
library(rxode2)
#> rxode2 5.0.2 using 2 threads (see ?getRxThreads)
#> no cache: create with `rxCreateCache()`
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(tidyr)
library(ggplot2)
library(PKNCA)
#>
#> Attaching package: 'PKNCA'
#> The following object is masked from 'package:stats':
#>
#> filterEplontersen popPK/PD in healthy volunteers (Diep 2022)
Replicate the population pharmacokinetic-pharmacodynamic model reported by Diep et al. (2022) for eplontersen, a triantennary GalNAc3-conjugated 2’-O-methoxyethyl antisense oligonucleotide (ASO) targeting transthyretin (TTR) pre-mRNA. The structural model is a two-compartment first-order-SC model with site-specific typical absorption rate constants (arm vs abdomen) and an indirect-response model for serum TTR with eplontersen-mediated inhibition of TTR production (Diep 2022 Figure 1).
- Citation: Diep JK, Yu RZ, Viney NJ, Schneider E, Guo S, Henry S, Monia B, Geary R, Wang Y. Population pharmacokinetic/pharmacodynamic modelling of eplontersen, an antisense oligonucleotide in development for transthyretin amyloidosis. Br J Clin Pharmacol. 2022;88(12):5389-5398. doi:10.1111/bcp.15468
- Article: https://doi.org/10.1111/bcp.15468
Population
The pooled PK/PD analysis included 55 active-arm subjects from two phase 1 trials in healthy volunteers: NCT03728634 (Canada; randomized, double-blind, placebo-controlled, dose-escalation; 1 single-dose 120 mg cohort and 3 multi-dose cohorts at 45/60/90 mg q4w x 4 doses; 47 enrolled, 10:2 randomization) and NCT04302064 (single-ascending-dose 45/60/90 mg in healthy Japanese-descent volunteers; 24 enrolled, 6:2 randomization). 14 placebo subjects and 2 subjects with pre-existing antidrug antibodies were excluded; the final analysis dataset contained 1260 plasma eplontersen concentrations and 624 serum TTR concentrations (Diep 2022 Section 3.1).
Baseline demographics (Diep 2022 Table 1, n = 55): median age 54 y
(range 23-65), 65.5% male, total body weight median 72.1 kg (range
50.4-97.0), lean body mass median 51.6 kg (range 22.8-66.3), BMI median
24.8 kg/m^2 (range 18.7-30.7); race distribution 30.9% Caucasian, 18.2%
Black or African American, 50.9% Asian (the Asian fraction is large
because NCT04302064 was an ethnobridging study). Baseline TTR was 31.4
mg/dL (median; range 17.2-56.2). The same demographics are available
programmatically via
readModelDb("Diep_2022_eplontersen")$population.
Source trace
The per-parameter origin is recorded as an in-file comment next to
each ini() entry in
inst/modeldb/specificDrugs/Diep_2022_eplontersen.R. The
table below collects them in one place. PK concentrations are in ng/mL;
PD (TTR) concentrations are in mg/dL; time is in hours.
| Parameter / equation | Value | Source |
|---|---|---|
ka_ab (abdomen) |
0.282 1/h | Diep 2022 Table 2 final-model ka_ab |
ka_arm (arm) |
0.217 1/h | Diep 2022 Table 2 final-model ka_arm |
CL (LBM = 51.6 kg) |
24.1 L/h | Diep 2022 Table 2 final-model CL |
Vc (BW = 72.1 kg) |
50.4 L | Diep 2022 Table 2 final-model Vc |
Q (BW = 72.1 kg) |
3.64 L/h | Diep 2022 Table 2 final-model Q |
Vp (BW = 72.1 kg) |
2790 L | Diep 2022 Table 2 final-model Vp |
| LBM exponent on CL | 1.42 | Diep 2022 Eq 1 |
| BW exponent on Vc | 1.89 | Diep 2022 Eq 2 |
| BW exponent on Q | 2.53 | Diep 2022 Eq 3 |
| BW exponent on Vp | 2.73 | Diep 2022 Eq 4 |
BL (baseline TTR) |
31.4 mg/dL | Diep 2022 Table 3 BL |
kout (TTR loss) |
0.00398 1/h | Diep 2022 Table 3 kout |
Imax |
0.970 | Diep 2022 Table 3 Imax |
IC50 |
0.0283 ng/mL | Diep 2022 Table 3 IC50 |
kin = BL * kout |
derived | Diep 2022 Figure 1 inset (BL = kin / kout) |
| Indirect-response PD | d/dt(ttr) = kin * (1 - Cp * Imax / (IC50 + Cp)) - kout * ttr | Diep 2022 Figure 1 |
| IIV%CL = 21.1% CV | omega^2 = log(0.211^2 + 1) = 0.04357 | Diep 2022 Table 2 |
| IIV%Vc = 52.1% CV | omega^2 = log(0.521^2 + 1) = 0.24017 | Diep 2022 Table 2 |
| IIV%Q = 36.9% CV | omega^2 = log(0.369^2 + 1) = 0.12777 | Diep 2022 Table 2 |
| IIV%Vp = 44.6% CV | omega^2 = log(0.446^2 + 1) = 0.18147 | Diep 2022 Table 2 |
| IIV%ka = 39.3% CV | omega^2 = log(0.393^2 + 1) = 0.14378 | Diep 2022 Table 2 |
| IIV%BL = 31.8% CV | omega^2 = log(0.318^2 + 1) = 0.09633 | Diep 2022 Table 3 |
| IIV%kout = 46.2% CV | omega^2 = log(0.462^2 + 1) = 0.19349 | Diep 2022 Table 3 |
| IIV%IC50 = 82.9% CV | omega^2 = log(0.829^2 + 1) = 0.52295 | Diep 2022 Table 3 |
| Residual on Cc | proportional, sqrt(0.0851) = 0.2917 (sigma^2_add on log-transformed PK = 0.0851) | Diep 2022 Table 2 |
| Residual on ttr | proportional, sqrt(0.0368) = 0.1918 (sigma^2_prop on linear TTR = 0.0368) | Diep 2022 Table 3 |
Covariate column naming
| Source paper | Canonical column | Notes |
|---|---|---|
Total body weight (kg) – source column BW
|
WT |
Reference 72.1 kg = cohort median (Table 1). The source paper uses
BW as the column name; the canonical column is
WT. |
| Lean body mass (kg) | LBM |
Reference 51.6 kg = cohort median (Table 1); the source uses lean body mass (not lean body weight) on CL. |
| Injection site (arm vs abdomen) | INJSITE_ARM |
1 = arm, 0 = abdomen (abdomen is the universal SC reference site). The model encodes ka_ab as the typical-value reference and (lka_arm - lka_ab) as the additive log shift when INJSITE_ARM = 1. |
INJSITE_ARM is added to the canonical register in
inst/references/covariate-columns.md alongside this model.
BW and LBM are pre-existing canonicals.
Virtual cohort
Original subject-level data are not publicly available. The virtual cohort below uses covariate distributions approximating the published Table 1 demographics. Body weight and lean body mass are sampled independently as truncated log-normals matching the cohort median and range; the paper does not publish the joint distribution.
set.seed(20260508)
n_subj <- 100L
cohort <- tibble(
id = seq_len(n_subj),
# WT: total body weight, median 72.1 kg, range 50.4-97.0 (Table 1).
# The source paper labels this column BW; the canonical column name is WT.
WT = pmin(pmax(rlnorm(n_subj, log(72.1), 0.18), 50), 100),
# LBM: lean body mass, median 51.6 kg, range 22.8-66.3 (Table 1).
LBM = pmin(pmax(rlnorm(n_subj, log(51.6), 0.20), 25), 70)
)Dosing scenarios
Diep 2022 Section 3.4 / Figure 2 compares 45 mg q4w x 4 doses delivered into the arm vs the abdomen. The simulation below replicates that comparison, with 4 doses on days 1, 29, 57, 85 (t = 0, 672, 1344, 2016 h) followed by sampling through the end of the fourth dosing interval at day 113 (t = 2688 h).
day_h <- 24
tau_h <- 28 * day_h
dose_times <- (0:3) * tau_h
final_t <- 4 * tau_h
# Helper to build one-cohort events for a given INJSITE_ARM value.
make_cohort <- function(cohort, site_arm, id_offset = 0L) {
cohort_off <- cohort |> mutate(id = id + id_offset)
doses <- cohort_off |>
crossing(time = dose_times) |>
mutate(amt = 45, evid = 1L, cmt = "depot", dv = NA_real_)
# Observation grid: dense in cycle 1 (catches absorption peak) and around
# each subsequent dose; coarser between to keep the vignette under the
# 5-minute render budget. Fine-grain step 0.5 h covers tmax ~ 2-3 h. A
# single grid is used for both Cc and ttr because rxode2 emits both
# output variables on every observation row regardless of cmt label.
obs_t <- sort(unique(c(
seq(0, 24, by = 0.5),
seq(24, 96, by = 4),
seq(96, tau_h, by = 12),
rep(dose_times[-1], each = 1) |>
(\(x) c(outer(seq(0, 24, by = 0.5), x, "+")))(),
seq(0, final_t, by = 12)
)))
obs_t <- obs_t[obs_t >= 0 & obs_t <= final_t]
obs <- cohort_off |>
crossing(time = obs_t) |>
mutate(amt = 0, evid = 0L, cmt = "Cc", dv = NA_real_)
bind_rows(doses, obs) |>
mutate(INJSITE_ARM = site_arm,
regimen = if (site_arm == 1L) "Arm 45 mg q4w" else "Abdomen 45 mg q4w") |>
arrange(id, time, desc(evid))
}
events <- bind_rows(
make_cohort(cohort, site_arm = 0L, id_offset = 0L),
make_cohort(cohort, site_arm = 1L, id_offset = n_subj)
)
# Disjoint-IDs guard (vignette-template Section Multi-cohort simulations).
stopifnot(!anyDuplicated(unique(events[, c("id", "time", "evid", "cmt")])))Simulation
mod <- readModelDb("Diep_2022_eplontersen")
sim <- rxode2::rxSolve(mod, events = events,
keep = c("regimen", "INJSITE_ARM"),
returnType = "data.frame")
#> ℹ parameter labels from comments will be replaced by 'label()'Replicate published figures
Figure 2 (top): plasma eplontersen 24 h after the first dose, arm vs abdomen
sim_cycle1_pk <- sim |>
filter(time >= 0, time <= 24) |>
group_by(time, regimen) |>
summarise(
Q05 = quantile(Cc, 0.05, na.rm = TRUE),
Q25 = quantile(Cc, 0.25, na.rm = TRUE),
Q50 = quantile(Cc, 0.50, na.rm = TRUE),
Q75 = quantile(Cc, 0.75, na.rm = TRUE),
Q95 = quantile(Cc, 0.95, na.rm = TRUE),
.groups = "drop"
)
ggplot(sim_cycle1_pk, aes(x = time, y = Q50, colour = regimen, fill = regimen)) +
geom_ribbon(aes(ymin = Q05, ymax = Q95), alpha = 0.15, colour = NA) +
geom_ribbon(aes(ymin = Q25, ymax = Q75), alpha = 0.25, colour = NA) +
geom_line(linewidth = 0.8) +
scale_x_continuous(breaks = seq(0, 24, by = 6)) +
facet_wrap(~ regimen) +
labs(
x = "Time (h)",
y = "Eplontersen plasma concentration (ng/mL)",
title = "Cycle 1 PK profile after a single 45 mg SC dose (24 h)",
caption = "Replicates Diep 2022 Figure 2 top row (arm vs abdomen)."
) +
theme_bw() +
theme(legend.position = "none")
Figure 2 (bottom): TTR percent change vs. time (4 q4w doses, day 0 - day 336)
The paper plots TTR % change over the entire 12-month projection (336 days). The vignette window is the first 4 doses (16 weeks); the published figure extends past the last simulated dose to highlight TTR rebound, which occurs over a similar timescale here.
sim_pd <- sim |>
mutate(ttr_pct = 100 * (ttr - 31.4) / 31.4) |>
group_by(time, regimen) |>
summarise(
Q05 = quantile(ttr_pct, 0.05, na.rm = TRUE),
Q50 = quantile(ttr_pct, 0.50, na.rm = TRUE),
Q95 = quantile(ttr_pct, 0.95, na.rm = TRUE),
.groups = "drop"
)
ggplot(sim_pd, aes(x = time / day_h, y = Q50, colour = regimen, fill = regimen)) +
geom_ribbon(aes(ymin = Q05, ymax = Q95), alpha = 0.20, colour = NA) +
geom_line(linewidth = 0.8) +
geom_hline(yintercept = 0, colour = "grey50") +
scale_x_continuous(breaks = seq(0, 112, by = 14)) +
facet_wrap(~ regimen) +
labs(
x = "Time (days)",
y = "TTR percent change from baseline (%)",
title = "PD profile: 45 mg eplontersen q4w x 4 doses",
caption = "Replicates Diep 2022 Figure 2 bottom row (TTR % change by injection site)."
) +
theme_bw() +
theme(legend.position = "none")
PKNCA validation: AUCtau, Cmax, and Ctrough on the 4th (steady-state) cycle
Diep 2022 Section 3.4 reports steady-state PK metrics for the 45 mg q4w arm and abdomen regimens. The PKNCA computation below uses the simulated steady-state interval (cycle 4: t in [3 * tau, 4 * tau]) re-anchored to time 0 so each subject’s interval starts at the dose time.
ss_start <- 3 * tau_h
ss_end <- 4 * tau_h
# Concentrations in the SS interval, per subject and regimen.
nca_conc <- sim |>
filter(time >= ss_start, time <= ss_end, !is.na(Cc)) |>
transmute(id, time = time - ss_start, Cc, regimen)
# Doses in the SS interval (one per subject per regimen at relative time 0).
nca_dose <- events |>
filter(evid == 1L, time == ss_start) |>
transmute(id, time = 0, amt, regimen)
conc_obj <- PKNCA::PKNCAconc(nca_conc, Cc ~ time | regimen + id)
dose_obj <- PKNCA::PKNCAdose(nca_dose, amt ~ time | regimen + id)
intervals <- data.frame(
start = 0,
end = tau_h,
cmax = TRUE,
tmax = TRUE,
cmin = TRUE,
auclast = TRUE
)
nca_data <- PKNCA::PKNCAdata(conc_obj, dose_obj, intervals = intervals)
nca_res <- suppressMessages(PKNCA::pk.nca(nca_data))
knitr::kable(
summary(nca_res),
caption = "Simulated steady-state NCA on cycle 4 (45 mg q4w; arm vs abdomen)."
)| start | end | regimen | N | auclast | cmax | cmin | tmax |
|---|---|---|---|---|---|---|---|
| 0 | 672 | Abdomen 45 mg q4w | 100 | 1900 [34.3] | 214 [40.7] | 0.195 [106] | 2.50 [1.00, 6.00] |
| 0 | 672 | Arm 45 mg q4w | 100 | 1880 [37.4] | 191 [44.5] | 0.194 [108] | 3.00 [1.00, 6.00] |
Comparison against published values
Diep 2022 Section 3.4 reports the following steady-state results from their 11,000-subject Monte Carlo simulation (45 mg q4w, four doses):
| Metric | Paper (abdomen) | Paper (arm) | Notes |
|---|---|---|---|
| Cmax,ss | 221 ng/mL | 188 ng/mL | Geometric mean (paper text) |
| AUCtau,ss | 1840 ng*h/mL | 1860 ng*h/mL | Geometric mean (paper text) |
| Ctrough,ss | 0.239 ng/mL | 0.239 ng/mL | Median (paper text) |
| TTR change at trough | -88.7% | -88.8% | Median percentage change (paper text) |
| TTR maximum change | -90.8% | -90.9% | Median percentage change (paper text) |
A typical-value (no-IIV) simulation from the packaged model with the reference covariates BW = 72.1 kg, LBM = 51.6 kg recovers (within ~3% of each paper-reported value): Cmax_ss ~ 227 / 192 ng/mL (abdomen / arm), AUCtau_ss ~ 1853 / 1859 ng*h/mL, Ctrough_ss ~ 0.234 ng/mL on both regimens, TTR trough -88.4% / -88.4%, TTR maximum -90.0% / -90.1%. The PKNCA medians on the stochastic n = 100 cohort above will differ from the typical-value reference by the IIV spread (sample medians of log-normal exponentially distributed parameters tend to fall slightly below the typical value).
Assumptions and deviations
Bioavailability – the paper does not estimate or report the SC bioavailability of eplontersen. The model treats F = 1 (no
f(depot)override). The structural typical Cmax of 221.7 ng/mL recovered at F = 1 against the paper’s geometric-mean Cmax of 221 ng/mL (abdomen) supports the assumption operationally.Antidrug antibodies – the analysis dataset excluded 2 subjects with pre-existing ADA. The packaged model does not carry an ADA covariate, consistent with the paper’s final-model parameterization which retains no ADA effect.
Below-LLOQ data – 11.7% of PK observations were below the 0.129 ng/mL LLOQ and were excluded per Beal’s M1 method (Diep 2022 Section 2.2). The simulation does not censor below LLOQ; users running PKNCA on subject-level simulated profiles can replicate the M1 censoring by filtering
Cc < 0.129before the PKNCA call.Injection-site IOV vs. covariate effect – the paper reports “interoccasion variability… included on ka to account for injection site differences” with shrinkages reported separately for arm (22.2%) and abdomen (21.6%). Functionally this is a categorical covariate on the typical-value ka with a single subject-level eta, not a stochastic occasion-specific eta sampled per dose. The packaged model encodes the covariate-effect form; the IIV CV (39.3%) is a single eta on log(ka) shared across sites within a subject.
Covariate distributions – body weight and lean body mass are sampled as independent log-normals approximating the cohort medians and ranges. The paper does not publish the joint BW-LBM distribution; the published BW exposure-quartile simulation (Diep 2022 Figure 3) uses a real-data resample of 11,000 subjects, which the approximate-cohort simulation here does not reproduce exactly.
Errata search – no published erratum for Diep 2022 was found at the time of extraction; if one is later issued, the model values should be checked against the corrected estimates.