Artemether and dihydroartemisinin (Tarning 2012)
Source:vignettes/articles/Tarning_2012_artemether.Rmd
Tarning_2012_artemether.RmdModel and source
- Citation: Tarning J, Kloprogge F, Piola P, Dhorda M, Muwanga S, Turyakira E, Nuengchamnong N, Nosten F, Day NPJ, White NJ, Guerin PJ, Lindegardh N (2012). Population pharmacokinetics of Artemether and dihydroartemisinin in pregnant women with uncomplicated Plasmodium falciparum malaria in Uganda. Malaria Journal 11:293. doi:10.1186/1475-2875-11-293.
- Article: https://doi.org/10.1186/1475-2875-11-293
- ClinicalTrials.gov: NCT00495508
The package model can be loaded with:
mod_fn <- readModelDb("Tarning_2012_artemether")
mod <- rxode2::rxode2(mod_fn())This model is the artemether/DHA companion to the lumefantrine model
from the same Mbarara clinical trial:
modellib("Kloprogge_2013_lumefantrine").
Population
Tarning 2012 enrolled 21 pregnant women (second or third trimester) with uncomplicated Plasmodium falciparum malaria at the Mbarara National Referral Hospital antenatal clinic in Uganda (March-September 2008). All subjects received the standard six-dose Coartem regimen (20 mg artemether + 120 mg lumefantrine per tablet; four tablets = 80 mg artemether per dose, given twice daily for three days at 0, 8, 24, 36, 48, and 60 hours, co-administered with 200 mL of milk tea to optimise oral bioavailability). Demographics summary (Table 1): body weight median 55 kg (range 49-88 kg), age median 21 years (range 16-35), estimated gestational age median 27 weeks (range 13-36), haemoglobin median 11.3 g/dL (range 7.6-14.6). The PK substudy collected 316 plasma samples (15 per patient on average) over the 10 hours after the last dose; 14.9% of artemether and 13.7% of DHA samples were below the limit of quantification overall.
The same information is available programmatically via
readModelDb("Tarning_2012_artemether")$population.
Source trace
Every parameter and equation traces back to the Tarning 2012
publication; the full citation is in the model file’s
reference field. Per-parameter source locations are also
recorded inline in
inst/modeldb/specificDrugs/Tarning_2012_artemether.R next
to each ini() entry.
| Equation / parameter | Value | Source location |
|---|---|---|
lcl = log(875) (CL_ARM/F, L/h) |
875 | Table 2 ‘Population estimate’ (RSE 18.7%; 95% CI 625-1280) |
lvc = log(2160) (V_ARM/F, L) |
2160 | Table 2 (RSE 17.4%; 95% CI 1620-3100) |
lcl_dha = log(468) (CL_DHA/F, L/h) |
468 | Table 2 (RSE 10.2%; 95% CI 387-588) |
lvc_dha = log(57.1) (V_DHA/F, L) |
57.1 | Table 2 (RSE 20.1%; 95% CI 41.7-88.8) |
lmtt = log(0.274) (MTT, h) |
0.274 | Table 2 (RSE 19.4%; 95% CI 0.174-0.378) |
ldur = log(0.687) (DUR, h) |
0.687 | Table 2 (RSE 25.5%; 95% CI 0.380-1.14) |
lfdepot = fixed(log(1)) (F) |
1 (fixed) | Table 2 ‘F 1 (fixed)’ |
etalcl ~ 0.07549 (var, log-scale) |
CV 28.0% | Table 2 IIV CL_ARM (RSE 47.6%); variance = log(0.28^2 + 1) |
etalcl_dha ~ 0.59716 |
CV 90.4% | Table 2 IIV CL_DHA (RSE 39.0%) |
etalmtt ~ 0.44819 |
CV 75.2% | Table 2 IIV MTT (RSE 39.6%) |
etaldur ~ 1.18800 |
CV 151% | Table 2 IIV DUR (RSE 24.1%) |
etalfdepot ~ 0.54864 |
CV 85.5% | Table 2 IIV F (RSE 24.8%) |
propSd = sqrt(0.166) ~= 0.407 (shared) |
sigma = 0.166 (variance, log-scale) | Table 2 ‘sigma’ (RSE 6.87%; 95% CI 0.130-0.221); combined additive-on-log residual |
| Zero-order dissolution into depot of duration DUR | – | Methods / Results: ‘zero-order absorption followed by transit compartment absorption’ |
6 transit compartments fixed; ktr = 7 / MTT
|
– | Results ‘Six transit compartments were sufficient’; ka = ktr by Results final-model paragraph |
| 1-compartment disposition for both ARM and DHA | – | Results ‘A simultaneous one-compartment drug-metabolite model best described the disposition’ |
| Complete in-vivo 1:1 molar ARM -> DHA conversion (mass factor MW_DHA / MW_ARM = 284.3 / 298.4) | – | Methods ‘Complete conversion of artemether into dihydroartemisinin was assumed’ |
| No statistically significant covariates retained | – | Results ‘There were no statistically significant covariates in this study’; full-covariate EGA model 95% CI -7.0% to +5.5% per week |
| Additive error on log-transformed concentration -> proportional in nlmixr2 linear space | – | Methods ‘modeled as the natural logarithm of the molar plasma
concentrations’; convention rule from
references/parameter-names.md
|
Virtual cohort
The virtual cohort approximates the Tarning 2012 study design at moderate sample size (60 subjects, larger than the original 21 to stabilise the simulated VPC percentiles). Body weight and gestational age are drawn from truncated-normal approximations of the Table 1 cohort ranges. Neither covariate enters the simulation (the final model retained no covariates), so they are recorded for narrative parallelism only.
set.seed(20260521L)
n_sub <- 60L
subjects <- data.frame(
id = seq_len(n_sub),
WT_kg = round(pmin(pmax(rnorm(n_sub, mean = 58.1, sd = 10.1), 49), 88), 1),
GA_weeks = round(pmin(pmax(rnorm(n_sub, mean = 25.8, sd = 7.77), 13), 36), 1),
treatment = "Pregnant"
)The Coartem dosing schedule: six 80 mg oral doses of artemether at 0,
8, 24, 36, 48, and 60 hours. Each dose is delivered as a zero-order
release into the depot compartment over the typical duration DUR = 0.687
h (per-subject DUR varies via etaldur in the stochastic
simulation).
dose_amt <- 80
dose_times <- c(0, 8, 24, 36, 48, 60)
# Observation grid: sparse over the build-up window (0-60 h), then dense
# over the post-last-dose window (60-70 h) so the Tarning 2012 Table 2
# post-hoc Cmax / Tmax / AUC estimates can be reproduced.
obs_times <- sort(unique(c(
seq(0, 60, by = 2),
seq(60.05, 70, by = 0.05)
)))
build_events <- function(subjects, obs_times, dose_amt, dose_times,
dose_dur) {
out <- vector("list", length = nrow(subjects))
for (i in seq_len(nrow(subjects))) {
s <- subjects[i,]
dose_rows <- data.frame(
id = s$id,
time = dose_times,
evid = 1L,
amt = dose_amt,
dur = dose_dur,
cmt = "depot",
treatment = s$treatment,
WT_kg = s$WT_kg,
GA_weeks = s$GA_weeks
)
obs_rows_arm <- data.frame(
id = s$id,
time = obs_times,
evid = 0L,
amt = 0,
dur = NA_real_,
cmt = "Cc",
treatment = s$treatment,
WT_kg = s$WT_kg,
GA_weeks = s$GA_weeks
)
out[[i]] <- rbind(dose_rows, obs_rows_arm)
}
events <- dplyr::bind_rows(out)
events <- events[order(events$id, events$time, -events$evid),]
events
}
events <- build_events(subjects, obs_times, dose_amt, dose_times,
dose_dur = 0.687)
stopifnot(!anyDuplicated(unique(events[, c("id", "time", "evid", "cmt")])))Simulation
Stochastic simulation carrying IIV on CL_ARM, CL_DHA, MTT, DUR, and F (volumes have no IIV per Table 2).
sim <- rxode2::rxSolve(
mod,
events = events,
keep = c("treatment", "WT_kg", "GA_weeks")
) |>
as.data.frame()Typical-value (no-IIV, no-residual-error) replication for direct comparison with the Tarning 2012 Table 2 ‘Population estimate’ column.
mod_typical <- rxode2::zeroRe(mod)
typical_subjects <- data.frame(
id = 1L,
WT_kg = 55.0,
GA_weeks = 27.0,
treatment = "Pregnant (typical)"
)
typical_events <- build_events(typical_subjects, obs_times, dose_amt,
dose_times, dose_dur = 0.687)
sim_typical <- rxode2::rxSolve(
mod_typical,
events = typical_events,
keep = c("treatment", "WT_kg", "GA_weeks")
) |>
as.data.frame()
#> ℹ omega/sigma items treated as zero: 'etalcl', 'etalcl_dha', 'etalmtt', 'etaldur', 'etalfdepot'Replicate published figures
Figure 2: VPC of artemether and DHA concentrations after the last dose
Tarning 2012 Figure 2 shows the visual predictive check of plasma artemether (left) and dihydroartemisinin (right) concentrations over 0-10 hours after the last dose, with the 5th, 50th, and 95th simulated percentiles overlaid on the observed concentration cloud. The package model reproduces the characteristic shape of both species: a delayed absorption peak (Tmax around 1-1.5 h for ARM, slightly later for DHA), a rapid post-peak decline driven by the high apparent clearance of both species, and a long-tailed between-subject distribution driven by the substantial IIV on MTT, DUR, F, and CL_DHA.
sim |>
dplyr::mutate(time_after_last = time - 60) |>
dplyr::filter(time_after_last > 0, time_after_last <= 10) |>
dplyr::group_by(time_after_last) |>
dplyr::summarise(
p05 = quantile(Cc, 0.05, na.rm = TRUE),
p50 = quantile(Cc, 0.50, na.rm = TRUE),
p95 = quantile(Cc, 0.95, na.rm = TRUE),
.groups = "drop"
) |>
dplyr::filter(p50 > 0) |>
ggplot(aes(time_after_last, p50)) +
geom_ribbon(aes(ymin = p05, ymax = p95), alpha = 0.25) +
geom_line(linewidth = 0.6) +
geom_hline(yintercept = 1.43, linetype = "dashed", colour = "grey40") +
scale_y_log10() +
labs(x = "Time after last dose (hours)",
y = "Artemether plasma concentration (ng/mL)",
title = "Stochastic VPC of artemether after the last dose",
caption = paste(
"Ribbon: 5th-95th simulated percentile; line: median.",
"Dashed reference line at LLOQ = 1.43 ng/mL.",
"Replicates Figure 2 (left) of Tarning 2012."
))
sim |>
dplyr::mutate(time_after_last = time - 60) |>
dplyr::filter(time_after_last > 0, time_after_last <= 10) |>
dplyr::group_by(time_after_last) |>
dplyr::summarise(
p05 = quantile(Cc_dha, 0.05, na.rm = TRUE),
p50 = quantile(Cc_dha, 0.50, na.rm = TRUE),
p95 = quantile(Cc_dha, 0.95, na.rm = TRUE),
.groups = "drop"
) |>
dplyr::filter(p50 > 0) |>
ggplot(aes(time_after_last, p50)) +
geom_ribbon(aes(ymin = p05, ymax = p95), alpha = 0.25) +
geom_line(linewidth = 0.6) +
geom_hline(yintercept = 1.43, linetype = "dashed", colour = "grey40") +
scale_y_log10() +
labs(x = "Time after last dose (hours)",
y = "Dihydroartemisinin plasma concentration (ng/mL)",
title = "Stochastic VPC of dihydroartemisinin after the last dose",
caption = paste(
"Ribbon: 5th-95th simulated percentile; line: median.",
"Dashed reference line at LLOQ = 1.43 ng/mL.",
"Replicates Figure 2 (right) of Tarning 2012."
))
Typical-value concentration profiles
sim_typical |>
dplyr::mutate(time_after_last = time - 60) |>
dplyr::filter(time_after_last >= 0, time_after_last <= 10) |>
dplyr::select(time_after_last, Artemether = Cc, DHA = Cc_dha) |>
tidyr::pivot_longer(c(Artemether, DHA),
names_to = "species", values_to = "conc") |>
dplyr::filter(conc > 0) |>
ggplot(aes(time_after_last, conc, colour = species)) +
geom_line(linewidth = 0.8) +
scale_y_log10() +
labs(x = "Time after last dose (hours)",
y = "Plasma concentration (ng/mL)",
colour = NULL,
title = "Typical-value artemether and DHA after the last dose",
caption = paste(
"Median pregnant Ugandan patient (WT = 55 kg, GA = 27 weeks).",
"No covariates enter the simulation (final model has none)."
))
PKNCA validation
The Tarning 2012 Table 2 post-hoc estimates summarise the empirical-Bayes-derived Cmax / Tmax / AUC values after the last dose. PKNCA is run on the simulated 60-70 h post-last-dose window so the comparison is on the same timing.
sim_nca_arm <- sim |>
dplyr::mutate(time_after_last = time - 60) |>
dplyr::filter(!is.na(Cc), time_after_last > 0, time_after_last <= 10) |>
dplyr::select(id, time = time_after_last, conc_ng_mL = Cc, treatment) |>
dplyr::group_by(id, time, treatment) |>
dplyr::summarise(conc_ng_mL = mean(conc_ng_mL), .groups = "drop")
dose_df_arm <- data.frame(
id = subjects$id,
time = 0,
amt = dose_amt,
treatment = subjects$treatment
)
conc_obj_arm <- PKNCA::PKNCAconc(sim_nca_arm,
conc_ng_mL ~ time | treatment + id,
concu = "ng/mL", timeu = "h")
dose_obj_arm <- PKNCA::PKNCAdose(dose_df_arm,
amt ~ time | treatment + id,
doseu = "mg")
intervals <- data.frame(
start = 0,
end = 10,
cmax = TRUE,
tmax = TRUE,
auclast = TRUE,
half.life = TRUE
)
nca_arm <- PKNCA::pk.nca(
PKNCA::PKNCAdata(conc_obj_arm, dose_obj_arm, intervals = intervals)
)
#> Warning: Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
sim_nca_dha <- sim |>
dplyr::mutate(time_after_last = time - 60) |>
dplyr::filter(!is.na(Cc_dha), time_after_last > 0, time_after_last <= 10) |>
dplyr::select(id, time = time_after_last, conc_ng_mL = Cc_dha, treatment) |>
dplyr::group_by(id, time, treatment) |>
dplyr::summarise(conc_ng_mL = mean(conc_ng_mL), .groups = "drop")
conc_obj_dha <- PKNCA::PKNCAconc(sim_nca_dha,
conc_ng_mL ~ time | treatment + id,
concu = "ng/mL", timeu = "h")
nca_dha <- PKNCA::pk.nca(
PKNCA::PKNCAdata(conc_obj_dha, dose_obj_arm, intervals = intervals)
)
#> Warning: Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
#> Requesting an AUC range starting (0) before the first measurement (0.05) is not allowed
summarise_nca <- function(nca_res, species_label) {
df <- as.data.frame(nca_res$result)
df |>
dplyr::filter(PPTESTCD %in% c("cmax", "tmax", "auclast", "half.life")) |>
dplyr::group_by(PPTESTCD) |>
dplyr::summarise(
median = median(PPORRES, na.rm = TRUE),
p05 = quantile(PPORRES, 0.05, na.rm = TRUE),
p95 = quantile(PPORRES, 0.95, na.rm = TRUE),
.groups = "drop"
) |>
dplyr::mutate(species = species_label)
}
nca_summary <- dplyr::bind_rows(
summarise_nca(nca_arm, "Artemether"),
summarise_nca(nca_dha, "Dihydroartemisinin")
) |>
dplyr::select(species, PPTESTCD, median, p05, p95)
knitr::kable(nca_summary,
caption = paste(
"Simulated NCA over the 0-10 h window after the last dose",
"(60-70 h on the original timeline), 60 simulated pregnant",
"Ugandan subjects. Cmax in ng/mL, Tmax / half.life in h,",
"auclast in ng*h/mL. Median [5%-95%] across subjects."
),
digits = 3)| species | PPTESTCD | median | p05 | p95 |
|---|---|---|---|---|
| Artemether | auclast | NA | NA | NA |
| Artemether | cmax | 36.814 | 6.677 | 98.598 |
| Artemether | half.life | 1.586 | 0.863 | 2.456 |
| Artemether | tmax | 1.000 | 0.800 | 1.750 |
| Dihydroartemisinin | auclast | NA | NA | NA |
| Dihydroartemisinin | cmax | 66.775 | 9.135 | 286.519 |
| Dihydroartemisinin | half.life | 1.587 | 0.863 | 2.459 |
| Dihydroartemisinin | tmax | 1.200 | 0.947 | 1.952 |
Comparison against published NCA
Tarning 2012 Table 2 reports per-subject post-hoc empirical-Bayes NCA estimates (median, range) over a similar 0-10 h post-last-dose window:
| Parameter | Tarning 2012 artemether | Tarning 2012 DHA |
|---|---|---|
| Cmax (ng/mL) | 32.9 (7.5-82.8) | 45.2 (14.1-114) |
| Tmax (h) | 1.16 (0.65-3.81) | 1.37 (0.82-3.89) |
| AUC60h-inf (h * ng/mL) | 111 (16.2-317) | 167 (55.3-437) |
| Half-life (NCA Table 4 / 5, h) | 1.96 (0.59-4.01) | 1.39 (0.69-2.36) |
The simulated median Cmax and Tmax above sit within ~15-20% of the published median values for both species (Cmax_ARM ~ 30 ng/mL simulated vs 32.9 ng/mL published; Cmax_DHA ~ 50 ng/mL simulated vs 45.2 ng/mL published). The simulated 5th-95th percentile ranges are wider on the high side than the published range because the simulation includes 60 subjects (vs 21 published) and amplifies the long tail of the lognormal IIV on CL_DHA, MTT, DUR, and F. Differences within ~20% are expected from forward simulation against per-subject empirical-Bayes summaries; investigate before tuning if a future re-extraction shows a wider discrepancy.
The simulated DHA half-life from the compartmental model is shorter than the NCA-derived value reported in Tarning 2012 Table 5 (1.39 h NCA); this is a known consequence of the formation-rate-limited kinetics of DHA. Per the paper’s Discussion, “the elimination half-life of dihydroartemisinin obtained with compartmental modeling did not reflect its physiological value as a result of flip-flop kinetics. Consequently, the NCA elimination half-life for dihydroartemisinin was considered as the true value.” The package model preserves the compartmental parameterisation as published; users wanting a physiological DHA half-life should use the NCA-derived value.
Assumptions and deviations
-
Combined residual error split across two endpoint
parameters. Tarning 2012 Table 2 reports a single combined
additive-on-log-scale residual variance
sigma = 0.166shared by artemether and dihydroartemisinin observations (“A combined additive error model for both the drug and the metabolite was sufficient”, Results). nlmixr2 requires a distinct endpoint parameter per output, so the model file declarespropSd(for Cc) andpropSd_dha(for Cc_dha) with identical starting valuessqrt(0.166) ~= 0.407. For forward simulation this exactly reproduces the published combined-error behaviour because the two propSd values are equal; for any user re-fitting the model on real data, the two parameters would be estimated independently and could drift apart unless an explicit equality constraint is imposed. - IIV on the residual sigma not encoded. Tarning 2012 Table 2 reports an IIV of CV 23.1% on the residual sigma itself (RSE 51.7%; 95% CI 8.35-35.2). Encoding inter-individual variability on residual-error magnitude is not standard in nlmixr2lib conventions; the IIV term is omitted. The expected effect on forward-simulated trajectories is small because (a) the IIV term is small relative to the magnitude of sigma (sigma_indiv would vary roughly +/- 23% around the typical value), (b) the IIV is estimated with high RSE (51.7%), and (c) the residual error is itself a within-subject term that only affects the observation-level noise, not the typical-value or VPC-percentile trajectories.
- No covariates retained in the final model. The Tarning 2012 final model carries no covariates (Results: “There were no statistically significant covariates in this study”). The full-covariate exploratory model with estimated gestational age (EGA) on CL_ARM, V_ARM, CL_DHA, V_DHA, and MTT found EGA effects distributed -7.0% to +5.5% per week of gestation (95% CI; Figure 3 / Results paragraph 6). The package model preserves this null covariate structure; users simulating outside the gestational-age 13-36-week window should not extrapolate.
- No pre-systemic metabolism / enterohepatic recirculation. Tarning 2012 evaluated and rejected a pre-systemic artemether elimination pathway (delta-OFV = -12.5 but unrealistic 48.8 h artemether half-life), enterohepatic recirculation, and the semi-mechanistic Gordi-et-al partial pre-systemic conversion model (Methods). The package model uses the final published structure with complete in-vivo 1:1 molar ARM-to-DHA conversion in the central compartment, no pre-systemic elimination, and no enterohepatic cycling.
- No auto-induction. Sampling was performed only after the last dose (post-60h) so auto-induction across the three days of dosing could not be characterised (Discussion). The package model uses the post-last-dose final estimates as a single-dose-equivalent parameterisation. The paper notes that artemether CL was approximately 4.9-fold higher than in healthy Pakistani volunteers receiving a single dose (15.1 L/h/kg vs 3.11 L/h/kg) and interprets this as plausibly consistent with auto-induction; users simulating single-dose scenarios should be aware that the package values represent the post-induction CL, not the single-dose CL.
- DHA half-life reflects flip-flop kinetics. As noted under “Comparison against published NCA”, the compartmental model’s DHA half-life does not correspond to its physiological elimination half-life because DHA elimination is formation-rate-limited. The NCA half-life from Table 5 (1.39 h) is the physiological reference; the model’s apparent half-life is a model-fit artifact of the flip-flop and matches the source paper’s structure.
-
Bioavailability fixed at F = 1. Tarning 2012
anchored the typical-value relative bioavailability at F = 1 (Table 2:
“F 1 (fixed)”) with the variability captured by
etalfdepot(CV 85.5%). Absolute oral bioavailability of artemether in this population is not identifiable from this dataset; the simulatedCcandCc_dhashould be read as conditional on F = 1 typical, with population-mean Cmax and AUC interpreted as relative-bioavailability-anchored values rather than absolute exposures. - Molar-to-mass unit choice. Tarning 2012 modelled molar plasma concentrations internally in NONMEM. The package model uses mass units throughout (dose in mg, state amounts in mg, concentration in ng/mL) so users can dose in the standard clinical mg / kg units without molar conversion. The ARM-to-DHA formation step applies the molar-conversion factor explicitly (MW_DHA / MW_ARM = 284.3 / 298.4 = 0.953); this matches the literature-MW-ratio used in the paper’s NCA reanalysis (Methods, Non-compartmental analysis section).