Computes the exposure metrics an exposure-response or population PK analysis actually needs — peak, trough and total exposure — for each group of by (by default each subject and analyte).

derive_exposure_metrics(
  pc,
  ex = NULL,
  by = c("USUBJID", "PARAMCD"),
  conc = "AVAL",
  time = "AFRLT",
  method = c("linear", "lin_up_log_down")
)

Arguments

pc

Concentration-time data: one record per subject, analyte and timepoint. Must contain the by variables plus the conc and time columns. The output of make_adpc() is a valid input.

ex

Optional dosing data with USUBJID and EXDOSE, and a dose time in AFRLT (or NFRLT when AFRLT is absent). Supplying it adds the dose amount and dose-normalised AUC, and switches CTROUGH to the pre-dose definition described above.

by

Character vector of grouping variables. One output record is produced per combination.

conc

Name of the concentration column in pc.

time

Name of the time column in pc, in hours since first dose.

method

AUC method: "linear" (default) or "lin_up_log_down".

Value

An eradam_exposure object: a tibble::tibble with one row per by group, carrying the AUC method in the method attribute.

Arithmetic

AUC is accumulated segment by segment between consecutive observation times \(t_1 < t_2\) with concentrations \(C_1, C_2\):

  • method = "linear" — the linear trapezoidal rule throughout, \((t_2 - t_1)(C_1 + C_2) / 2\).

  • method = "lin_up_log_down" — linear on ascending segments, and on descending segments with two positive endpoints the log trapezoidal rule \((t_2 - t_1)(C_1 - C_2) / \ln(C_1 / C_2)\). This is the "linear up / log down" rule used by non-compartmental analysis software (for example Certara Phoenix WinNonlin) and it is the more accurate choice on a log-linear elimination phase. A descending segment that reaches zero falls back to the linear rule, because the log rule is undefined there.

Records with a missing concentration are dropped before any metric is computed, so AUCLST runs from the first to the last quantifiable concentration. If you want values below the limit of quantification imputed rather than dropped, run make_adpc() first and pass its result here — the BLQ policy is applied there, on purpose, so that the imputation rule is visible in the delivered concentration dataset rather than buried in a summary statistic.

Conventions

The parameter names (CMAX, TMAX, CMIN, CTROUGH, AUCLST) follow the CDISC SDTM PPTESTCD controlled terminology for pharmacokinetic parameters. The one-row-per-group wide layout is a choice made by this package, not a standard: CDISC would carry these as one record per parameter in PP/ADPP. Wide is what a modelling or exposure-response join wants, and make_ader() consumes it directly.

CTROUGH is also a package convention. When ex supplies more than one dose, it is the last observation at or before the final dose time — the pre-dose trough. Otherwise it is the last observation in the profile, that is, the concentration at the end of the observed interval.

Output structure

VariableMeaningSource
USUBJIDUnique subject identifierpc (grouping variable)
PARAMCDAnalyte codepc (grouping variable)
NOBSNumber of quantifiable observations usedDerived
TFIRSTTime of the first quantifiable concentrationDerived from time
TLASTTime of the last quantifiable concentrationDerived from time
CMAXMaximum observed concentrationDerived from conc
TMAXTime of the maximum observed concentration (first if tied)Derived
CMINMinimum observed quantifiable concentrationDerived from conc
CTROUGHConcentration at the last observation time in the profileDerived
AUCLSTArea under the curve from the first to the last quantifiable concentrationDerived by trapezoidal rule
AUCMTHAUC method actually applied (linear or lin_up_log_down)Argument method
DOSEDose amount in effect (sum of doses in ex per subject)ex
AUCLSTDDose-normalised AUCLST (AUCLST / DOSE)Derived (only when ex supplied)

Limits

This function computes only what can be read off the observed points. It fits no model, so it returns no \(\lambda_z\), half-life, AUCINF or percentage extrapolated — those need a terminal regression and live in derive_terminal_phase(), which reports the fit diagnostics with the estimate. An area over a window other than first-to-last observation lives in derive_partial_auc().

Still absent from the package after those two: steady-state parameters (AUCTAU, CAVG, accumulation and fluctuation ratios), clearance and volume (CL, CLF, VZ, VZF, MRT), moment curves (AUMC), and sparse-sampling variance estimation.

See also

make_ader(), which turns these metrics into an exposure-response dataset; derive_terminal_phase() for \(\lambda_z\), half-life and AUCINF; derive_partial_auc() for AUC over a stated window.

Examples

pc <- eradam_example("pc")
ex <- eradam_example("ex")

exp_lin <- derive_exposure_metrics(pc, ex)
exp_lin
#> 
#> ── eradam exposure metrics ─────────────────────────────────────────────────────
#>  48 group(s) | AUC method: linear
#>  Analytes: DRUGX, DRUGXM1
#>  CMAX: median 543 (range 122.4 to 2276)
#>  CTROUGH: median 108.8 (range 14.76 to 458.3)
#>  AUCLST: median 15100 (range 3262 to 52750)
#> # A tibble: 48 × 13
#>    USUBJID    PARAMCD  NOBS TFIRST TLAST  CMAX  TMAX  CMIN CTROUGH AUCLST AUCMTH
#>    <chr>      <chr>   <int>  <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl>  <dbl> <chr> 
#>  1 ERADAM01-… DRUGX      11  0.58   48.0  378.  2.03  14.8    14.8  6619. linear
#>  2 ERADAM01-… DRUGXM1    11  0.497  48.0  153. 28.0   21.4    21.4  3862. linear
#>  3 ERADAM01-… DRUGX      11  0.499  48.0  491.  3.97  53.6    53.6 11468. linear
#>  4 ERADAM01-… DRUGXM1    11  0.558  48.1  196. 28.0   46.0    46.0  5793. linear
#>  5 ERADAM01-… DRUGX      11  0.504  48.0  448. 28     85.0    85.0 11919. linear
#>  6 ERADAM01-… DRUGXM1    11  0.566  48.0  205. 25.1   61.2    61.2  5900. linear
#>  7 ERADAM01-… DRUGX      11  0.506  48.1  430. 28.0   53.7    54.3 10329. linear
#>  8 ERADAM01-… DRUGXM1    11  0.579  48.0  179. 28.0   50.0    50.0  5265. linear
#>  9 ERADAM01-… DRUGX      11  0.538  48.0  329. 25.1   25.6    25.6  6868. linear
#> 10 ERADAM01-… DRUGXM1    11  0.567  48.0  122. 28.0   25.7    25.7  3262. linear
#> # ℹ 38 more rows
#> # ℹ 2 more variables: DOSE <dbl>, AUCLSTD <dbl>

# the linear up / log down variant, on the parent analyte only
derive_exposure_metrics(
  pc[pc$PARAMCD == "DRUGX", ], ex,
  method = "lin_up_log_down"
)
#> 
#> ── eradam exposure metrics ─────────────────────────────────────────────────────
#>  24 group(s) | AUC method: lin_up_log_down
#>  Analytes: DRUGX
#>  CMAX: median 941.3 (range 278 to 2276)
#>  CTROUGH: median 136.9 (range 14.76 to 458.3)
#>  AUCLST: median 21250 (range 6142 to 51510)
#> # A tibble: 24 × 13
#>    USUBJID    PARAMCD  NOBS TFIRST TLAST  CMAX  TMAX  CMIN CTROUGH AUCLST AUCMTH
#>    <chr>      <chr>   <int>  <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl>  <dbl> <chr> 
#>  1 ERADAM01-… DRUGX      11  0.58   48.0  378.  2.03  14.8    14.8  6142. lin_u…
#>  2 ERADAM01-… DRUGX      11  0.499  48.0  491.  3.97  53.6    53.6 10940. lin_u…
#>  3 ERADAM01-… DRUGX      11  0.504  48.0  448. 28     85.0    85.0 11527. lin_u…
#>  4 ERADAM01-… DRUGX      11  0.506  48.1  430. 28.0   53.7    54.3  9868. lin_u…
#>  5 ERADAM01-… DRUGX      11  0.538  48.0  329. 25.1   25.6    25.6  6514. lin_u…
#>  6 ERADAM01-… DRUGX      11  0.494  48.0  278. 28.0   30.6    30.7  6311. lin_u…
#>  7 ERADAM01-… DRUGX      11  0.509  48.0  362. 28.0   34.3    34.3  7644. lin_u…
#>  8 ERADAM01-… DRUGX      11  0.521  48.1  615.  2.01  71.3   194.  12507. lin_u…
#>  9 ERADAM01-… DRUGX      11  0.547  48.0  849.  2.04  92.5    95.8 18671. lin_u…
#> 10 ERADAM01-… DRUGX      11  0.48   48.0 1185. 25.0  211.    211.  29978. lin_u…
#> # ℹ 14 more rows
#> # ℹ 2 more variables: DOSE <dbl>, AUCLSTD <dbl>

# a hand-checkable curve: 0, 10, 20, 10 at 0, 1, 2, 3 h
curve <- data.frame(
  USUBJID = "X-001", PARAMCD = "DRUGX",
  AFRLT = c(0, 1, 2, 3), AVAL = c(0, 10, 20, 10)
)
derive_exposure_metrics(curve)$AUCLST   # 5 + 15 + 15 = 35
#> [1] 35