conc <- c(0.5, 0.3, 0, 0.1, 0, 0.0, 0.02)
time <- c(0, 1, 2, 3, 4, 5, 6 )
# Drop BLQ (0) values
clean.conc.blq(conc, time, conc.blq = "drop") conc time
1 0.50 0
2 0.30 1
4 0.10 3
7 0.02 6
clean.conc.blq()clean.conc.na()interp.extrap.conc()pk.calc.half.life()pk.calc.auc.all()check.interval.specification()setRoute() and setDuration()get.parameter.deps()PKNCA.options()PKNCA.choose.option()pknca_routes() and pknca_match_route() (≥ 0.13.0)pknca_difftime_to_unit() (≥ 0.13.0)PKNCA exports several lower-level utility functions useful for data preparation, interval validation, and direct computation outside the full PKNCAdata → pk.nca() pipeline.
clean.conc.blq()Applies the BLQ-handling rule to a concentration vector before calculation. The full analysis pipeline applies this automatically, but clean.conc.blq() is useful for pre-processing or testing your own rule.
conc time
1 0.50 0
2 0.30 1
4 0.10 3
7 0.02 6
conc time
1 0.50 0
2 0.30 1
3 0.05 2
4 0.10 3
5 0.05 4
6 0.05 5
7 0.02 6
The conc.blq argument accepts:
"drop" — remove BLQ rows"keep" — keep BLQ rows as-isclean.conc.na()Removes or replaces NA concentrations. Internally called before AUC computation.
conc time
1 0.5 0
3 0.3 2
4 0.1 3
conc time
1 0.5 0
2 0.0 1
3 0.3 2
4 0.1 3
5 0.0 4
interp.extrap.conc()Interpolates or extrapolates a concentration at a target time given a known concentration-time profile. The aucint.* parameters use it internally when an interval boundary falls between two observed timepoints and no dosing data are given; with dosing data they use the dose-aware interp.extrap.conc.dose() instead.
[1] 3.535534
[1] 0.2626444
[1] 0.3497357
The method (linear vs log-linear) follows the auc.method setting. Extrapolation beyond Tlast requires supplying lambda.z (the terminal slope) — the function never estimates λz itself, and without lambda.z the result is NA. The example above estimates it with pk.calc.half.life(), covered next. For interpolation around dose events, see the Dose-Aware Interpolation chapter and the vignette Methods for Dose-Aware Interpolation and Extrapolation.
pk.calc.half.life()Runs the full curve-stripping algorithm on raw concentration-time data and returns the selected half-life, λz, and associated diagnostics. Useful for batch processing outside the standard pipeline.
half.life lambda.z r.squared lambda.z.n.points lambda.z.time.first span.ratio
1 14.30438 0.048457 0.9999997 3 9.05 1.071001
This is the same function called internally by pk.nca() when half.life = TRUE.
pk.calc.auc.all()Computes AUC directly on a concentration-time vector with the chosen integration method. It returns the AUC with a "method" attribute (≥ 0.13.0) naming that method — the text that pk.nca() moves into the PPANMETH column of its results.
[1] 147.2347
attr(,"method")
[1] "AUC: lin up/log down"
The attribute carries through arithmetic, so wrap the result in as.numeric() before comparing it to a bare number (for example with identical() or testthat::expect_equal()):
[1] 147.2347
Other direct AUC functions:
| Function | AUC type |
|---|---|
pk.calc.auc.last() |
AUC to last measurable concentration |
pk.calc.auc.all() |
AUC to the last observation including post-Tlast BLQ values (as 0) |
pk.calc.auc.inf.obs() |
AUC extrapolated to ∞ (observed Clast) |
pk.calc.auc.inf.pred() |
AUC extrapolated to ∞ (predicted Clast) |
These are the building blocks behind the AUC parameters in the registry; the interval forms (pk.calc.aucint() and relatives) are described in the AUC chapter. Integration methods are compared in AUC integration methods.
check.interval.specification()Validates an intervals data frame before passing it to PKNCAdata(). Returns the data frame with all parameter columns filled in (missing columns defaulted to FALSE).
my_intervals <- data.frame(
start = 0,
end = Inf,
auclast = TRUE,
cmax = TRUE
)
# Returns the full expanded interval spec
expanded <- check.interval.specification(my_intervals)
# Which parameters are requested? (drop the start/end bounds columns first)
param_cols <- setdiff(names(expanded), c("start", "end"))
param_cols[sapply(expanded[1, param_cols], isTRUE)][1] "auclast" "cmax"
[1] "Column(s) 'start' missing from interval specification"
This is useful for debugging custom interval definitions before running the full analysis.
Total registered parameters: 237
$start
NULL
$end
NULL
$auclast
NULL
$auclast_se
[1] "auclast"
$auclast_df
[1] "auclast"
Dose-normalized parameters:
- auclast.dn
- aucall.dn
- aucinf.obs.dn
- aucinf.pred.dn
- aumclast.dn
- aumcall.dn
- aumcinf.obs.dn
- aumcinf.pred.dn
- cmax.dn
- cmin.dn
- clast.obs.dn
- clast.pred.dn
- cav.dn
- ctrough.dn
- clr.last.dn
- clr.obs.dn
- clr.pred.dn
setRoute() and setDuration()After creating a PKNCAdose object, you can change the route or infusion duration without rebuilding from scratch.
Found column named route, using it for the attribute of the same name.
Found column named duration, using it for the attribute of the same name.
route duration
1 intravascular 0.5
This is useful when you want to test how route assumption changes affect MRT or Vss calculations without re-specifying the PKNCAdose object from scratch.
get.parameter.deps()By default, returns the downstream parameters that depend on a given parameter — the results that would be affected if it fails or is excluded.
[1] "adj_tobit_residual" "adj.r.squared" "aucinf.obs"
[4] "aucinf.obs_df" "aucinf.obs_se" "aucinf.obs.dn"
[7] "aucinf.pred" "aucinf.pred.dn" "aucint.inf.obs"
[10] "aucint.inf.pred" "aucivall_df" "aucivall_se"
[13] "aucivinf.obs" "aucivinf.obs_df" "aucivinf.obs_se"
[16] "aucivinf.pred" "aucivlast_df" "aucivlast_se"
[19] "aucivpbextinf.obs" "aucivpbextinf.pred" "aucpext.obs"
[22] "aucpext.pred" "aumcinf.obs" "aumcinf.obs_df"
[25] "aumcinf.obs_se" "aumcinf.obs.dn" "aumcinf.pred"
[28] "aumcinf.pred.dn" "aumcint.inf.obs" "aumcint.inf.pred"
[31] "aumcivall_df" "aumcivall_se" "aumcivinf.obs"
[34] "aumcivinf.obs_df" "aumcivinf.obs_se" "aumcivinf.pred"
[37] "aumcivlast_df" "aumcivlast_se" "cav.int.inf.obs"
[40] "cav.int.inf.pred" "cl.int.inf.obs" "cl.int.inf.pred"
[43] "cl.iv.obs" "cl.iv.pred" "cl.obs"
[46] "cl.pred" "clast.pred" "clast.pred.dn"
[49] "f.int.obs" "f.int.pred" "f.obs"
[52] "f.pred" "half.life" "kel.int.inf.obs"
[55] "kel.int.inf.pred" "kel.iv.obs" "kel.iv.pred"
[58] "kel.obs" "kel.pred" "lambda.z"
[61] "lambda.z.corrxy" "lambda.z.n.points" "lambda.z.n.points_blq"
[64] "lambda.z.time.first" "lambda.z.time.last" "mrt.int.inf.obs"
[67] "mrt.int.inf.pred" "mrt.iv.obs" "mrt.iv.pred"
[70] "mrt.ivmd.obs" "mrt.ivmd.pred" "mrt.md.obs"
[73] "mrt.md.pred" "mrt.obs" "mrt.pred"
[76] "r.squared" "ratio.aucinf.obs" "ratio.aucinf.pred"
[79] "span.ratio" "thalf.eff.iv.obs" "thalf.eff.iv.pred"
[82] "thalf.eff.obs" "thalf.eff.pred" "tobit_residual"
[85] "vss.int.inf.obs" "vss.int.inf.pred" "vss.iv.obs"
[88] "vss.iv.pred" "vss.ivmd.obs" "vss.ivmd.pred"
[91] "vss.md.obs" "vss.md.pred" "vss.obs"
[94] "vss.pred" "vz.all" "vz.int.all"
[97] "vz.int.inf.obs" "vz.int.inf.pred" "vz.int.last"
[100] "vz.iv.all" "vz.iv.last" "vz.iv.obs"
[103] "vz.iv.pred" "vz.ivint.all" "vz.ivint.last"
[106] "vz.last" "vz.obs" "vz.pred"
For the opposite direction, recursive = TRUE (≥ 0.13.0) returns what a parameter is calculated from, following each dependency back to the raw inputs (such as conc, time, and dose) and the arguments of the calculation functions along the way, including the options they read:
[1] "adj.r.squared.factor" "allow.tmax.in.half.life"
[3] "check" "conc"
[5] "conc.blq" "conc.na"
[7] "dose" "duration.dose"
[9] "first.tmax" "hl_method"
[11] "lloq" "manually.selected.points"
[13] "max.hl.points" "min.hl.points"
[15] "min.hl.start.time" "options"
[17] "r.squared.factor" "time"
[19] "time.dose" "tobit_n_points_penalty"
[21] "tobit_optim_control"
The registry entry lists only the direct dependencies:
PKNCA.options()PKNCA.options() with no arguments returns the full named list of current settings:
$adj.r.squared.factor
[1] 1e-04
$r.squared.factor
[1] NA
$max.missing
[1] 0.5
$auc.method
[1] "lin up/log down"
$conc.na
[1] "drop"
$conc.blq
$conc.blq$first
[1] "keep"
$conc.blq$middle
[1] "drop"
$conc.blq$last
[1] "keep"
$debug
NULL
$first.tmax
[1] TRUE
$first.tmin
[1] TRUE
$allow.tmax.in.half.life
[1] FALSE
$keep_interval_cols
NULL
$min.hl.points
[1] 3
$max.hl.points
[1] Inf
$min.hl.start.time
[1] 0
$min.span.ratio
[1] 2
$max.aucinf.pext
[1] 20
$min.hl.r.squared
[1] 0.9
$progress
[1] TRUE
$tau.choices
[1] NA
$auto.interval.method
[1] "builder"
$auto.interval.tolerance
[1] 0.05
$single.dose.aucs
start end auclast auclast_se auclast_df aucall aucall_se aucall_df aumclast
1 0 24 TRUE FALSE FALSE FALSE FALSE FALSE FALSE
2 0 Inf FALSE FALSE FALSE FALSE FALSE FALSE FALSE
aumclast_se aumclast_df aumcall aumcall_se aumcall_df aucint.last aucint.all
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
aumcint.last aumcint.all c0 cmax cmin tmax tmin tlast tfirst clast.obs
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE
cl.last cl.all cl.int.all cl.int.last mrt.last mrt.all mrt.int.all
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
mrt.int.last mrt.iv.last vss.last vss.iv.last vss.all vss.int.all
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
vss.int.last cav cav.int.last cav.int.all ctrough cstart ptr tlag
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
deg.fluc swing ceoi aucabove.predose.all aucabove.trough.all count_conc
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
count_conc_measured totdose volpk ae clr.last clr.obs clr.pred fe
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
ertlst ermax ertmax erint erlst ratio.cmax ratio.auclast ratio.aucint.last
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
ratio.aucint.all sparse_auclast sparse_auc_se sparse_auc_df sparse_aumclast
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
sparse_aumc_se sparse_aumc_df time_above aucivlast aucivlast_se aucivlast_df
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
aucivall aucivall_se aucivall_df aucivint.last aucivint.all aucivpbextlast
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
aucivpbextall aucivpbextint.last aucivpbextint.all aumcivlast aumcivlast_se
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
aumcivlast_df aumcivall aumcivall_se aumcivall_df aumcivint.last
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
aumcivint.all half.life r.squared adj.r.squared lambda.z.corrxy lambda.z
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE TRUE FALSE FALSE FALSE FALSE
lambda.z.time.first lambda.z.time.last lambda.z.n.points clast.pred
1 FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE
span.ratio tobit_residual adj_tobit_residual lambda.z.n.points_blq
1 FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE
thalf.eff.last thalf.eff.iv.last kel.last kel.iv.last kel.all kel.int.all
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
kel.int.last cl.iv.all cl.iv.last cl.ivint.all cl.ivint.last cl.sparse.last
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
f.last f.int.last f.int.all mrt.sparse.last mrt.iv.all mrt.ivint.all
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
mrt.ivint.last vz.all vz.int.all vz.int.last vz.iv.all vz.iv.last
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
vz.ivint.all vz.ivint.last vz.last vss.iv.all vss.ivint.all vss.ivint.last
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
vss.sparse.last aucinf.obs aucinf.obs_se aucinf.obs_df aucinf.pred
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE TRUE FALSE FALSE FALSE
aumcinf.obs aumcinf.obs_se aumcinf.obs_df aumcinf.pred aucint.inf.obs
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
aucint.inf.pred aumcint.inf.obs aumcint.inf.pred aucivinf.obs aucivinf.obs_se
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
aucivinf.obs_df aucivinf.pred aucivpbextinf.obs aucivpbextinf.pred
1 FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE
aumcivinf.obs aumcivinf.obs_se aumcivinf.obs_df aumcivinf.pred aucpext.obs
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
aucpext.pred kel.iv.all kel.ivint.all kel.ivint.last kel.sparse.last cl.obs
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
cl.pred cl.int.inf.obs cl.int.inf.pred cl.iv.obs cl.iv.pred f.obs f.pred
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
f.int.obs f.int.pred mrt.obs mrt.pred mrt.int.inf.obs mrt.int.inf.pred
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
mrt.iv.obs mrt.iv.pred mrt.md.obs mrt.md.pred mrt.ivmd.obs mrt.ivmd.pred
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
vz.obs vz.pred vz.int.inf.obs vz.int.inf.pred vz.iv.obs vz.iv.pred
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
vz.sparse.last vss.obs vss.pred vss.iv.obs vss.iv.pred vss.md.obs vss.md.pred
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
vss.ivmd.obs vss.ivmd.pred vss.int.inf.obs vss.int.inf.pred cav.int.inf.obs
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
cav.int.inf.pred ratio.aucinf.obs ratio.aucinf.pred thalf.eff.obs
1 FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE
thalf.eff.pred thalf.eff.iv.obs thalf.eff.iv.pred kel.obs kel.pred kel.iv.obs
1 FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE
kel.iv.pred kel.int.inf.obs kel.int.inf.pred auclast.dn aucall.dn
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
aucinf.obs.dn aucinf.pred.dn aumclast.dn aumcall.dn aumcinf.obs.dn
1 FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE
aumcinf.pred.dn cmax.dn cmin.dn clast.obs.dn clast.pred.dn cav.dn ctrough.dn
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE
clr.last.dn clr.obs.dn clr.pred.dn
1 FALSE FALSE FALSE
2 FALSE FALSE FALSE
$allow_partial_missing_units
[1] FALSE
$hl_method
[1] "log-linear"
$sparse_lambda_z_se
[1] "delta"
$tobit_n_points_penalty
[1] 0
$tobit_optim_control
list()
PKNCA_options_defaults() (≥ 0.13.0) returns the default value of one or more options (or all of them, with no argument) without changing the current settings — unlike PKNCA.options(default = TRUE), which resets them:
$auc.method
[1] "lin up/log down"
$min.hl.points
[1] 3
$max.hl.points
[1] Inf
PKNCA.options.describe() returns the description of a single option; see the Workflow Overview page for the full option reference table, and the vignette Options for Controlling PKNCA.
[1] "The method used to calculate the AUC and related statistics. Options are: \"lin up/log down\", \"linear\", \"lin-log\""
PKNCA.choose.option()Selects a value from either the local options list passed to PKNCAdata() or the global PKNCA.options() defaults. Useful when writing custom parameter functions that need to respect session-level settings.
[1] 3
[1] 5
pknca_routes() and pknca_match_route() (≥ 0.13.0)pknca_routes() lists the routes PKNCA distinguishes. With synonyms = TRUE it returns a table of the spellings data use for a route (“po”, “intravenous bolus”, CDISC ROUTE terms, …), the route PKNCA uses for each, and the PKNCAdose(route = ) value it implies; pknca_match_route() looks a character vector up in that table, giving NA for spellings it does not know. A spelling that does not say bolus or infusion maps to the generic "iv".
[1] "extravascular" "iv_bolus" "iv_infusion"
[4] "iv_continuous_infusion"
synonym route dose_route
1 extravascular extravascular extravascular
2 oral extravascular extravascular
3 po extravascular extravascular
4 per os extravascular extravascular
5 by mouth extravascular extravascular
6 peroral extravascular extravascular
route dose_route
1 extravascular extravascular
2 iv_bolus intravascular
3 iv intravascular
4 <NA> <NA>
The dose_route column is ready to pass to the route argument of PKNCAdose().
pknca_difftime_to_unit() (≥ 0.13.0)Converts a difftime (such as a collection duration computed as the difference of two date-times) into a number in an analysis time unit — the conversion pk.nca() applies to date-time data. A value that is not a difftime is an error.
Date-time concentration and dose times are covered in the date-time chapter.
Applications that assemble PKNCA objects from user data can run the same checks PKNCA runs, before calling the constructors:
| Function | What it checks |
|---|---|
assert_conc_time() |
Concentrations and times are valid numbers and the times are sorted |
assert_impute_method() |
An imputation specification resolves to known methods, the way PKNCAdata() and pk.nca() resolve it |
PKNCA_impute_fun_list() |
The imputation function names an imputation string resolves to |
assert_PKNCAconc(), assert_PKNCAdose(), assert_PKNCAresults() |
The object has the expected class |
[1] "Assertion on 'time' failed: Must be sorted."
[[1]]
[1] "PKNCA_impute_method_start_conc0"
[[2]]
[1] "PKNCA_impute_method_start_predose" "PKNCA_impute_method_start_conc0"
[1] "The following imputation functions were not found: PKNCA_impute_method_start_bogus. The imputation setting must be an imputation method or a column of the intervals."
Imputation methods themselves are described in the imputation chapter.
pkgdown reference: clean.conc.blq() · clean.conc.na() · interp.extrap.conc() · pk.calc.half.life() · pk.calc.auc.all() · check.interval.specification() · get.interval.cols() · PKNCAdose() · setRoute() · setDuration() · get.parameter.deps() · PKNCA.options() · PKNCA.options.describe() · PKNCA.choose.option() · PKNCA_options_defaults() · pknca_routes() · pknca_match_route() · pknca_difftime_to_unit() · assert_conc_time() · assert_impute_method() · PKNCA_impute_fun_list() · assert_PKNCAconc()
---
title: "Utility Functions"
---
```{r setup, include=FALSE}
library(PKNCA)
library(dplyr)
conflicted::conflicts_prefer(dplyr::filter, dplyr::select, .quiet = TRUE)
```
## Overview
PKNCA exports several lower-level utility functions useful for data preparation, interval validation, and direct computation outside the full `PKNCAdata` → `pk.nca()` pipeline.
---
## BLQ concentration handling: `clean.conc.blq()`
Applies the BLQ-handling rule to a concentration vector **before** calculation. The full analysis pipeline applies this automatically, but `clean.conc.blq()` is useful for pre-processing or testing your own rule.
```{r}
conc <- c(0.5, 0.3, 0, 0.1, 0, 0.0, 0.02)
time <- c(0, 1, 2, 3, 4, 5, 6 )
# Drop BLQ (0) values
clean.conc.blq(conc, time, conc.blq = "drop")
```
```{r}
# Replace BLQ with half the LLOQ (= 0.05 here)
clean.conc.blq(conc, time, conc.blq = 0.05)
```
The `conc.blq` argument accepts:
- `"drop"` — remove BLQ rows
- `"keep"` — keep BLQ rows as-is
- A number — substitute BLQ values with that number
---
## NA concentration handling: `clean.conc.na()`
Removes or replaces NA concentrations. Internally called before AUC computation.
```{r}
conc_na <- c(0.5, NA, 0.3, 0.1, NA)
time_na <- c(0, 1, 2, 3, 4)
# Default: drop NAs
clean.conc.na(conc_na, time_na, conc.na = "drop")
```
```{r}
# Replace NAs with 0
clean.conc.na(conc_na, time_na, conc.na = 0)
```
---
## Concentration interpolation / extrapolation: `interp.extrap.conc()`
Interpolates or extrapolates a concentration at a target time given a known concentration-time profile. The `aucint.*` parameters use it internally when an interval boundary falls between two observed timepoints and no dosing data are given; with dosing data they use the dose-aware `interp.extrap.conc.dose()` instead.
```{r}
conc_ex <- c(10, 8, 5, 2.5, 1)
time_ex <- c(0, 1, 2, 4, 8)
# Interpolate at t = 3 (between t=2 and t=4)
interp.extrap.conc(conc = conc_ex, time = time_ex, time.out = 3)
```
```{r}
# Extrapolate beyond the last sample (t = 12):
# estimate lambda.z first, then pass it to interp.extrap.conc()
hl_ex <- pk.calc.half.life(conc = conc_ex, time = time_ex)
hl_ex$lambda.z
interp.extrap.conc(conc = conc_ex, time = time_ex, time.out = 12,
lambda.z = hl_ex$lambda.z)
```
The method (linear vs log-linear) follows the `auc.method` setting. Extrapolation beyond Tlast requires supplying `lambda.z` (the terminal slope) — the function never estimates λz itself, and without `lambda.z` the result is `NA`. The example above estimates it with `pk.calc.half.life()`, covered next. For interpolation around dose events, see the [Dose-Aware Interpolation chapter](dose-aware-interpolation.qmd) and the vignette [Methods for Dose-Aware Interpolation and Extrapolation](https://humanpred.github.io/pknca/articles/v21-methods-for-dose-aware-interpolation-and-extrapolation.html).
---
## Direct half-life computation: `pk.calc.half.life()`
Runs the full curve-stripping algorithm on raw concentration-time data and returns the selected half-life, λz, and associated diagnostics. Useful for batch processing outside the standard pipeline.
```{r}
subj1 <- as.data.frame(Theoph) |> filter(Subject == "1")
hl_result <- pk.calc.half.life(
conc = subj1$conc,
time = subj1$Time,
options = PKNCA.options()
)
hl_result[c("half.life", "lambda.z", "r.squared", "lambda.z.n.points",
"lambda.z.time.first", "span.ratio")]
```
This is the same function called internally by `pk.nca()` when `half.life = TRUE`.
---
## Direct AUC computation: `pk.calc.auc.all()`
Computes AUC directly on a concentration-time vector with the chosen integration method. It returns the AUC with a `"method"` attribute (≥ 0.13.0) naming that method — the text that `pk.nca()` moves into the `PPANMETH` column of its results.
```{r}
pk.calc.auc.all(
conc = subj1$conc,
time = subj1$Time,
method = "lin up/log down"
)
```
The attribute carries through arithmetic, so wrap the result in `as.numeric()` before comparing it to a bare number (for example with `identical()` or `testthat::expect_equal()`):
```{r}
as.numeric(pk.calc.auc.all(conc = subj1$conc, time = subj1$Time,
method = "lin up/log down"))
```
Other direct AUC functions:
| Function | AUC type |
|---|---|
| `pk.calc.auc.last()` | AUC to last measurable concentration |
| `pk.calc.auc.all()` | AUC to the last observation including post-Tlast BLQ values (as 0) |
| `pk.calc.auc.inf.obs()` | AUC extrapolated to ∞ (observed Clast) |
| `pk.calc.auc.inf.pred()` | AUC extrapolated to ∞ (predicted Clast) |
These are the building blocks behind the AUC parameters in the registry; the interval forms (`pk.calc.aucint()` and relatives) are described in the [AUC chapter](auc-methods.qmd). Integration methods are compared in [AUC integration methods](https://humanpred.github.io/pknca/articles/v23-auc-integration-methods.html).
---
## Validating interval specifications: `check.interval.specification()`
Validates an intervals data frame before passing it to `PKNCAdata()`. Returns the data frame with all parameter columns filled in (missing columns defaulted to `FALSE`).
```{r}
my_intervals <- data.frame(
start = 0,
end = Inf,
auclast = TRUE,
cmax = TRUE
)
# Returns the full expanded interval spec
expanded <- check.interval.specification(my_intervals)
# Which parameters are requested? (drop the start/end bounds columns first)
param_cols <- setdiff(names(expanded), c("start", "end"))
param_cols[sapply(expanded[1, param_cols], isTRUE)]
```
```{r}
# Invalid specification — missing start column — raises an error;
# the handler returns the error message
tryCatch(
check.interval.specification(data.frame(end = Inf, auclast = TRUE)),
error = function(e) conditionMessage(e)
)
```
This is useful for debugging custom interval definitions before running the full analysis.
---
## Listing all available parameters
```{r}
cols <- get.interval.cols()
cat("Total registered parameters:", length(cols), "\n")
# Show first few with their dependency lists
lapply(head(cols, 5), function(x) x$depends)
```
```{r}
# All dose-normalized parameters
dn_params <- names(cols)[endsWith(names(cols), ".dn")]
cat("Dose-normalized parameters:\n")
cat(paste(" -", dn_params), sep = "\n")
```
---
## Modifying PKNCAdose after creation: `setRoute()` and `setDuration()`
After creating a `PKNCAdose` object, you can change the route or infusion duration without rebuilding from scratch.
```{r}
d_dose_u <- data.frame(subject = "1", dose = 100, time = 0)
o_dose_u <- PKNCAdose(d_dose_u, dose ~ time | subject, route = "extravascular")
# Change to intravascular
o_dose_iv <- setRoute(o_dose_u, route = "intravascular")
# Add infusion duration (0.5 h = 30 min)
o_dose_inf <- setDuration(o_dose_iv, duration = 0.5)
# Verify
o_dose_inf$data[c("route", "duration")]
```
This is useful when you want to test how route assumption changes affect MRT or Vss calculations without re-specifying the `PKNCAdose` object from scratch.
---
## Getting parameter dependents: `get.parameter.deps()`
By default, returns the downstream parameters that depend on a given parameter — the results that would be affected if it fails or is excluded.
```{r}
get.parameter.deps("half.life")
```
For the opposite direction, `recursive = TRUE` (≥ 0.13.0) returns what a parameter is calculated from, following each dependency back to the raw inputs (such as `conc`, `time`, and `dose`) and the arguments of the calculation functions along the way, including the options they read:
```{r}
get.parameter.deps("vss.obs", recursive = TRUE)
```
The registry entry lists only the direct dependencies:
```{r}
get.interval.cols()[["vss.obs"]]$depends
```
---
## Listing all current option values: `PKNCA.options()`
`PKNCA.options()` with no arguments returns the full named list of current settings:
```{r}
PKNCA.options()
```
`PKNCA_options_defaults()` (≥ 0.13.0) returns the default value of one or more options (or all of them, with no argument) without changing the current settings — unlike `PKNCA.options(default = TRUE)`, which resets them:
```{r}
PKNCA_options_defaults(c("auc.method", "min.hl.points", "max.hl.points"))
```
`PKNCA.options.describe()` returns the description of a single option; see the [Workflow Overview](workflow.qmd) page for the full option reference table, and the vignette [Options for Controlling PKNCA](https://humanpred.github.io/pknca/articles/v40-options-for-controlling-PKNCA.html).
```{r}
PKNCA.options.describe("auc.method")
```
---
## Choosing an option value: `PKNCA.choose.option()`
Selects a value from either the local `options` list passed to `PKNCAdata()` or the global `PKNCA.options()` defaults. Useful when writing custom parameter functions that need to respect session-level settings.
```{r}
# With no local override, returns the global default
PKNCA.choose.option("min.hl.points", options = list())
```
```{r}
# With a local override, the local value wins
PKNCA.choose.option("min.hl.points", options = list(min.hl.points = 5))
```
---
## Routes of administration: `pknca_routes()` and `pknca_match_route()` (≥ 0.13.0)
`pknca_routes()` lists the routes PKNCA distinguishes. With `synonyms = TRUE` it returns a table of the spellings data use for a route ("po", "intravenous bolus", CDISC `ROUTE` terms, ...), the route PKNCA uses for each, and the `PKNCAdose(route = )` value it implies; `pknca_match_route()` looks a character vector up in that table, giving `NA` for spellings it does not know. A spelling that does not say bolus or infusion maps to the generic `"iv"`.
```{r}
pknca_routes()
head(pknca_routes(synonyms = TRUE))
pknca_match_route(c("PO", "INTRAVENOUS BOLUS", "iv", "nasal spray"))
```
The `dose_route` column is ready to pass to the `route` argument of `PKNCAdose()`.
---
## Converting durations: `pknca_difftime_to_unit()` (≥ 0.13.0)
Converts a `difftime` (such as a collection duration computed as the difference of two date-times) into a number in an analysis time unit — the conversion `pk.nca()` applies to date-time data. A value that is not a `difftime` is an error.
```{r}
pknca_difftime_to_unit(as.difftime(90, units = "mins"), "hr")
```
Date-time concentration and dose times are covered in the [date-time chapter](datetime.qmd).
---
## Checking inputs before building objects (≥ 0.13.0)
Applications that assemble PKNCA objects from user data can run the same checks PKNCA runs, before calling the constructors:
| Function | What it checks |
|---|---|
| `assert_conc_time()` | Concentrations and times are valid numbers and the times are sorted |
| `assert_impute_method()` | An imputation specification resolves to known methods, the way `PKNCAdata()` and `pk.nca()` resolve it |
| `PKNCA_impute_fun_list()` | The imputation function names an imputation string resolves to |
| `assert_PKNCAconc()`, `assert_PKNCAdose()`, `assert_PKNCAresults()` | The object has the expected class |
```{r}
# Unsorted times are an error
tryCatch(
assert_conc_time(conc = c(1, 2, 3), time = c(0, 2, 1)),
error = function(e) conditionMessage(e)
)
# An imputation chain resolves to one function name per method
PKNCA_impute_fun_list(c("start_conc0", "start_predose,start_conc0"))
# An unknown method is an error
tryCatch(
assert_impute_method("start_bogus"),
error = function(e) conditionMessage(e)
)
```
Imputation methods themselves are described in the [imputation chapter](imputation.qmd).
---
::: {.callout-note icon=false appearance="minimal"}
**pkgdown reference:** [clean.conc.blq()](https://humanpred.github.io/pknca/reference/clean.conc.blq.html) · [clean.conc.na()](https://humanpred.github.io/pknca/reference/clean.conc.na.html) · [interp.extrap.conc()](https://humanpred.github.io/pknca/reference/interp.extrap.conc.html) · [pk.calc.half.life()](https://humanpred.github.io/pknca/reference/pk.calc.half.life.html) · [pk.calc.auc.all()](https://humanpred.github.io/pknca/reference/pk.calc.auxc.html) · [check.interval.specification()](https://humanpred.github.io/pknca/reference/check.interval.specification.html) · [get.interval.cols()](https://humanpred.github.io/pknca/reference/get.interval.cols.html) · [PKNCAdose()](https://humanpred.github.io/pknca/reference/PKNCAdose.html) · [setRoute()](https://humanpred.github.io/pknca/reference/setRoute.html) · [setDuration()](https://humanpred.github.io/pknca/reference/setDuration.html) · [get.parameter.deps()](https://humanpred.github.io/pknca/reference/get.parameter.deps.html) · [PKNCA.options()](https://humanpred.github.io/pknca/reference/PKNCA.options.html) · [PKNCA.options.describe()](https://humanpred.github.io/pknca/reference/PKNCA.options.describe.html) · [PKNCA.choose.option()](https://humanpred.github.io/pknca/reference/PKNCA.choose.option.html) · [PKNCA_options_defaults()](https://humanpred.github.io/pknca/reference/PKNCA_options_defaults.html) · [pknca_routes()](https://humanpred.github.io/pknca/reference/pknca_concepts.html) · [pknca_match_route()](https://humanpred.github.io/pknca/reference/pknca_match_route.html) · [pknca_difftime_to_unit()](https://humanpred.github.io/pknca/reference/pknca_difftime_to_unit.html) · [assert_conc_time()](https://humanpred.github.io/pknca/reference/assert_conc_time.html) · [assert_impute_method()](https://humanpred.github.io/pknca/reference/assert_impute_method.html) · [PKNCA_impute_fun_list()](https://humanpred.github.io/pknca/reference/PKNCA_impute_fun_list.html) · [assert_PKNCAconc()](https://humanpred.github.io/pknca/reference/assert_PKNCAdata.html)
:::