library(tidyverse)
library(PKNCA)
data(Theoph)
theoph_conc <- as_tibble(Theoph) %>%
transmute(ID = Subject, TIME = Time, CONC = conc)
theoph_dose <- as_tibble(Theoph) %>%
distinct(Subject, Dose) %>%
transmute(ID = Subject, TIME = 0, DOSE = Dose)
conc_obj <- PKNCAconc(CONC ~ TIME | ID, data = theoph_conc)
dose_obj <- PKNCAdose(DOSE ~ TIME | ID, data = theoph_dose)
intervals_df <- data.frame(
start = 0,
end = Inf,
auclast = TRUE,
aucinf.obs = TRUE
)
nca_data <- PKNCAdata(conc_obj, dose_obj, intervals = intervals_df)AUC Calculation Choices: Linear vs Log Trapezoidal and Why It Matters
Big idea: AUC is “just integration,” but the integration rule is a choice. Linear vs log trapezoidal assumptions can change AUC — especially on the declining phase.
Learning Objectives
By the end of this lesson, you will be able to:
- Explain what the trapezoidal rule is doing conceptually.
- Describe when linear trapezoidal vs log trapezoidal is more appropriate.
- Run NCA in PKNCA and extract AUC outputs robustly across environments.
- Communicate how and why AUC rules affect interpretation.
Key Ideas
- NCA estimates AUC by integrating concentration over time using trapezoids.
- Linear trapezoidal connects points with straight lines.
- Log trapezoidal is often used on the declining phase because PK decline is frequently exponential.
- Many workflows use linear-up / log-down (linear on the rising phase, log on the declining phase).
- PKNCA uses linear-up/log-down by default.
- Differences are usually small in rich data — but can matter in sparse sampling or steep declines.
Conceptual Warm-Up: What the Trapezoidal Rule Is Doing
For two adjacent timepoints \((t_1, C_1)\) and \((t_2, C_2)\):
Linear trapezoid
\[ AUC_{1\to2}^{(lin)} = \frac{(C_1 + C_2)}{2} (t_2 - t_1) \]
Log trapezoid (declining phase)
When \(C_2 < C_1\) and decline is approximately exponential, a common log trapezoid form is:
\[ AUC_{1\to2}^{(log)} = \frac{(C_1 - C_2)}{\ln(C_1) - \ln(C_2)} (t_2 - t_1) \]
Log trapezoidal requires positive concentrations. If you have zeros/BLQ values, you must handle them intentionally.
Setup: Run NCA on Theoph (Baseline)
Run NCA Using Linear-Up / Log-Down (Default)
PKNCA.options(auc.method = "lin up/log down")
res_default <- pk.nca(nca_data)
raw_default <- as.data.frame(res_default)
sort(unique(raw_default$PPTESTCD)) [1] "adj.r.squared" "aucinf.obs" "auclast"
[4] "clast.obs" "clast.pred" "half.life"
[7] "lambda.z" "lambda.z.n.points" "lambda.z.time.first"
[10] "lambda.z.time.last" "r.squared" "span.ratio"
[13] "tlast" "tmax"
Run NCA Using Pure Linear Trapezoidal
PKNCA.options(auc.method = "linear")
res_linear <- pk.nca(nca_data)
raw_linear <- as.data.frame(res_linear)Extract AUC Results
Across versions/settings, the AUC to the last observed concentration is reported as auclast. We can extract it together with aucinf.obs after reshaping the results table.
extract_auc <- function(raw_df) {
raw_df %>%
filter(PPTESTCD %in% c("aucinf.obs", "auclast")) %>%
select(ID, PPTESTCD, PPORRES) %>%
pivot_wider(names_from = PPTESTCD, values_from = PPORRES) %>%
select(ID, auclast, aucinf.obs)
}
auc_default <- extract_auc(raw_default)
auc_linear <- extract_auc(raw_linear)Compare Results
compare_auc <- auc_default %>%
rename(
auclast_default = auclast,
aucinf_default = aucinf.obs
) %>%
inner_join(
auc_linear %>%
rename(
auclast_linear = auclast,
aucinf_linear = aucinf.obs
),
by = "ID"
) %>%
mutate(
d_auclast = auclast_linear - auclast_default,
d_aucinf = aucinf_linear - aucinf_default
)
compare_auc %>% head()# A tibble: 6 × 7
ID auclast_default aucinf_default auclast_linear aucinf_linear d_auclast
<ord> <dbl> <dbl> <dbl> <dbl> <dbl>
1 6 71.7 82.2 73.8 84.3 2.08
2 7 88.0 101. 90.8 104. 2.78
3 8 86.8 102. 88.6 104. 1.75
4 11 77.9 86.9 80.1 89.1 2.20
5 3 95.9 106. 99.3 110. 3.41
6 2 88.7 97.4 91.5 100. 2.80
# ℹ 1 more variable: d_aucinf <dbl>
This comparison shows how the integration rule alone can slightly change the estimated exposure.
How to Communicate the Impact
When AUC differs between rules, explain why:
- Linear assumes straight-line change between samples.
- Log assumes exponential decline (often realistic post-peak).
- Differences tend to show up most on the declining phase and with sparse sampling.
In regulated contexts, consistency matters most:
Use the same rule across arms/studies when comparing exposure.
Strategies
- Default to reproducibility: document the rule and software version.
- Use linear-up/log-down when justified.
- Treat rule choice as an assumption: “this is the curve shape between samples.”
- When comparing arms, keep the rule fixed.
Common Mistakes
- Assuming AUC is “objective” without specifying interpolation rules.
- Treating software defaults as invisible rather than documented assumptions.
- Using log methods with non-positive concentrations.
- Forgetting sparse sampling makes rule choice more impactful.
Practice Problems
- Conceptual: On which part of a typical oral PK curve would you expect log trapezoidal to matter most, and why?
- Executable: Build a subject-level table with
auclastandaucinf.obs. - Executable: Compute the percent extrapolated contribution: \(100\times(AUC_{0-\infty}-AUC_{0-tlast})/AUC_{0-\infty}\).
1. Conceptual:
On the declining phase. If decline is approximately exponential, log trapezoids match the curve shape between samples better than straight lines.
2. Subject-level AUC table:
auc_tbl <- extract_auc(raw_default)
auc_tbl %>% head()# A tibble: 6 × 3
ID auclast aucinf.obs
<ord> <dbl> <dbl>
1 6 71.7 82.2
2 7 88.0 101.
3 8 86.8 102.
4 11 77.9 86.9
5 3 95.9 106.
6 2 88.7 97.4
3. Percent extrapolated contribution:
auc_tbl %>%
mutate(
pct_extra = 100 * (aucinf.obs - auclast) / aucinf.obs
) %>%
arrange(desc(pct_extra)) %>%
head(12)# A tibble: 12 × 4
ID auclast aucinf.obs pct_extra
<ord> <dbl> <dbl> <dbl>
1 1 147. 215. 31.5
2 10 136. 168. 19.2
3 8 86.8 102. 15.0
4 9 83.9 97.5 13.9
5 5 118. 136. 13.3
6 7 88.0 101. 12.9
7 6 71.7 82.2 12.8
8 11 77.9 86.9 10.4
9 4 103. 114. 10.1
10 3 95.9 106. 9.66
11 2 88.7 97.4 8.88
12 12 115. 126. 8.43
Summary
AUC is estimated, not directly observed.
- Linear trapezoids assume straight-line change.
- Log trapezoids assume exponential decline (often more realistic post-peak).
- PKNCA allows global or calculation-specific control of the interpolation rule.
- The interpolation rule is an assumption that should be documented.
- Consistency matters most when comparing exposure across arms/studies.
- Document your software version and interpolation rule.
- Expect differences mainly on the declining phase (and in sparse sampling).
- Don’t use log trapezoids with zeros/BLQ without a plan.
- When comparing arms, keep rules fixed and document assumptions.