derive_partial_auc.RdArea under the concentration-time curve between two caller-stated times —
AUC[0, 24], AUC over a dosing interval, or any other window a protocol
asks for. The SAS idiom this replaces is a PROC EXPAND / RETAIN trapezoid
loop over a WHERE-clipped copy of the concentration dataset, with the
window edges hand-interpolated before the loop.
Concentration-time data: one record per subject, analyte and
timepoint. The output of make_adpc() is a valid input.
Window edges, in the units of time. start must be less
than end.
Character vector of grouping variables. One output record is produced per combination.
Name of the concentration column in pc.
Name of the time column in pc, in hours since first dose.
AUC method: "linear" (default) or "lin_up_log_down". Also
selects the edge interpolation rule, as described above.
An eradam_partial object: a tibble::tibble with one row per by
group.
This is where implementations silently disagree, so it is stated rather than
assumed. When start or end falls between two observed timepoints, a
concentration is interpolated at that time and used as the endpoint of
the first (or last) trapezoid:
method = "linear" — linear interpolation between the two bracketing
observations.
method = "lin_up_log_down" — logarithmic interpolation when the
bracketing segment is descending and both bracketing concentrations are
strictly positive, linear otherwise. This matches the trapezoid rule
actually being applied on that segment.
When start or end coincides exactly with an observed time, the observed
concentration is used and nothing is interpolated; INTRPFL reports which
happened. AUCINT over the full observed window is therefore identical to
AUCLST from derive_exposure_metrics() with the same method.
The window must lie inside the observed range of each profile. If
start is before the first observation or end is after the last, the
result is NA with the reason in AUCINTRS — this function never
back-extrapolates to time zero and never forward-extrapolates with
\(\lambda_z\). Both of those are real conventions used elsewhere, and
picking one silently is exactly how two "AUC0-24" columns end up
disagreeing. For the forward tail, use derive_terminal_phase(), which
extrapolates explicitly and reports how much it extrapolated.
In practice this bites at the pre-dose sample: if the 0 h result is below
the limit of quantification and still missing, the profile's first usable
observation is the first post-dose sample and AUC[0, t] refuses. Run
make_adpc() first so the BLQ policy has given that record a value — the
policy is then visible in the delivered dataset instead of hidden inside
this function.
AUCINT is the CDISC PPTESTCD code for an area between two times.
AUCINTLL, AUCINTUL, NOBSINT, INTRPFL and AUCINTRS are this
package's names, as is the wide one-row-per-profile layout. The
interpolation rules above are the ones non-compartmental analysis software
uses; the refusal to extrapolate past the observed range is this package's
choice.
One window per call. For several windows, call it once per window and
rbind() the results — AUCINTLL and AUCINTUL identify each. Steady-state
AUCTAU is not a separate parameter here: pass the dosing interval as
start and end on a steady-state profile and you get the same number under
the name AUCINT, but none of the other steady-state parameters (CAVG,
accumulation ratio, fluctuation) are derived.
| Variable | Meaning | Source |
USUBJID | Unique subject identifier | pc (grouping variable) |
PARAMCD | Analyte code | pc (grouping variable) |
AUCINTLL | Lower edge of the requested window | Argument start |
AUCINTUL | Upper edge of the requested window | Argument end |
AUCINT | Area under the curve between AUCINTLL and AUCINTUL | Derived |
NOBSINT | Number of points used, counting interpolated window edges | Derived |
INTRPFL | "Y" when a window edge had to be interpolated between observations | Derived |
AUCINTRS | Reason AUCINT is NA, in words; NA when it was derived | Derived |
# 0, 10, 20, 10 at 0, 1, 2, 3 h — AUC over the whole window is 35
curve <- data.frame(
USUBJID = "X-001", PARAMCD = "DRUGX",
AFRLT = c(0, 1, 2, 3), AVAL = c(0, 10, 20, 10)
)
derive_partial_auc(curve, 0, 3)$AUCINT
#> [1] 35
# a window with an interpolated edge: at 1.5 h the linear rule gives 15
derive_partial_auc(curve, 1.5, 3)[, c("AUCINT", "NOBSINT", "INTRPFL")]
#> # A tibble: 1 × 3
#> AUCINT NOBSINT INTRPFL
#> <dbl> <int> <chr>
#> 1 23.8 3 Y
# AUC[0, 24] on the shipped fixtures. The raw 0 h sample is below the limit
# of quantification, so run make_adpc() first to give it a value — otherwise
# the window starts before the first usable observation and the answer is
# NA with the reason, which is the point of the rule.
pc <- eradam_example("pc")
derive_partial_auc(pc[pc$PARAMCD == "DRUGX", ], 0, 24)$AUCINTRS[1]
#> [1] "Window [0, 24] is not inside the observed range [0.58, 48.006]; no extrapolation is done."
adpc <- make_adpc(pc, eradam_example("adsl"), eradam_example("ex"), blq = "half")
derive_partial_auc(adpc[adpc$PARAMCD == "DRUGX", ], 0, 24)
#>
#> ── eradam partial AUC ──────────────────────────────────────────────────────────
#> ℹ 24 profile(s) | window [0, 24] | AUC method: linear
#> ℹ AUCINT derived for 24/24 profile(s)
#> ℹ AUCINT: median 10110 (range 3147 to 24010)
#> ℹ 24 profile(s) needed an interpolated window edge
#> # A tibble: 24 × 8
#> USUBJID PARAMCD AUCINTLL AUCINTUL AUCINT NOBSINT INTRPFL AUCINTRS
#> <chr> <chr> <dbl> <dbl> <dbl> <int> <chr> <chr>
#> 1 ERADAM01-001 DRUGX 0 24 3304. 9 Y NA
#> 2 ERADAM01-002 DRUGX 0 24 5514. 9 Y NA
#> 3 ERADAM01-003 DRUGX 0 24 5515. 9 Y NA
#> 4 ERADAM01-004 DRUGX 0 24 4997. 9 Y NA
#> 5 ERADAM01-005 DRUGX 0 24 3147. 9 Y NA
#> 6 ERADAM01-006 DRUGX 0 24 3164. 9 Y NA
#> 7 ERADAM01-007 DRUGX 0 24 3788. 9 Y NA
#> 8 ERADAM01-008 DRUGX 0 24 6307. 9 Y NA
#> 9 ERADAM01-009 DRUGX 0 24 9743. 9 Y NA
#> 10 ERADAM01-010 DRUGX 0 24 14396. 9 Y NA
#> # ℹ 14 more rows