From 3201ac7b56d5776e0a27cf0572d48177c491c782 Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Sat, 13 Jun 2026 22:31:09 +0000 Subject: [PATCH 1/2] docs: clarify three-state include/exclude_half.life semantics The TRUE/FALSE/NA semantics of include_half.life and exclude_half.life, and the rule that only one may be in use per interval, were not documented in the function/argument reference. This left it unclear that initializing a column to all-FALSE (rather than NA) engages that mechanism and can trigger "Cannot both include and exclude half-life points for the same interval" when downstream code also sets inclusions. - Document the three per-point states (TRUE acts, FALSE does not, NA undefined) and the "in use unless entirely NA" activation rule in the roxygen for PKNCAconc() and pk.nca.interval(); regenerate man pages. - Add the mutual-exclusivity note to the half-life vignette and fix a mislabeled "include" example (section text + chunk comments). Co-Authored-By: Claude Opus 4.8 --- NEWS.md | 7 +++++++ R/class-PKNCAconc.R | 7 ++++++- R/pk.calc.all.R | 18 +++++++++++++----- man/PKNCAconc.Rd | 7 ++++++- man/pk.nca.interval.Rd | 20 ++++++++++++++------ vignettes/v06-half-life-calculation.Rmd | 13 ++++++++++--- 6 files changed, 56 insertions(+), 16 deletions(-) diff --git a/NEWS.md b/NEWS.md index 46ab9f96..ba52dc23 100644 --- a/NEWS.md +++ b/NEWS.md @@ -37,6 +37,13 @@ the dosing including dose amount and route. ## Improvements +* Documentation for `include_half.life` and `exclude_half.life` now describes + the three-state (`TRUE`/`FALSE`/`NA`) per-point behavior, clarifies that a + column counts as "in use" whenever it is not entirely `NA` (so an all-`FALSE` + column still engages the method), and states that only one of the two may be + in use for the same interval. The half-life vignette gains the same note and + fixes a mislabeled "include" example. + * The sparse NCA vignette now explains how subjects are grouped: sparse parameters pool all subjects that share the same concentration grouping variables with the subject column removed (#530). diff --git a/R/class-PKNCAconc.R b/R/class-PKNCAconc.R index fc16d6ff..ee34f629 100644 --- a/R/class-PKNCAconc.R +++ b/R/class-PKNCAconc.R @@ -31,7 +31,12 @@ #' name in the dataset of the points to exclude from the half-life calculation #' (still using normal curve-stripping selection rules for the other points) #' or to include for the half-life (using specifically those points and -#' bypassing automatic curve-stripping point selection). See the "Half-Life +#' bypassing automatic curve-stripping point selection). The column is logical +#' with three meaningful states per point: `TRUE` acts on the point, `FALSE` +#' does not, and `NA` is undefined. A column is treated as "in use" for an +#' interval unless it is entirely `NA`, so leave it `NA` (rather than `FALSE`) +#' where the mechanism should not apply. Only one of `exclude_half.life` and +#' `include_half.life` may be in use for a given interval. See the "Half-Life #' Calculation" vignette for more details on the use of these arguments. #' @param lloq (optional) The lower limit of quantification used by the Tobit #' half-life method (`hl_method = "tobit"`). Either the name of a column in diff --git a/R/pk.calc.all.R b/R/pk.calc.all.R index 6ce41bd4..24417c66 100644 --- a/R/pk.calc.all.R +++ b/R/pk.calc.all.R @@ -351,11 +351,19 @@ pk.nca.intervals <- function(data_conc, data_dose, data_intervals, sparse, #' @param impute_method The method to use for imputation as a character string #' @param interval One row of an interval definition (see #' [check.interval.specification()] for how to define the interval. -#' @param include_half.life An optional boolean vector of the concentration -#' measurements to include in the half-life calculation. If given, no -#' half-life point selection will occur. -#' @param exclude_half.life An optional boolean vector of the concentration -#' measurements to exclude from the half-life calculation. +#' @param include_half.life An optional logical vector (one value per +#' concentration measurement) of points to include in the half-life +#' calculation. If in use, automatic half-life point selection does not occur +#' and exactly the `TRUE` points are used. `TRUE` includes a point, `FALSE` +#' does not, and `NA` is undefined; the vector is "in use" for the interval +#' unless it is entirely `NA` (so an all-`FALSE` vector still counts as in +#' use). At most one of `include_half.life` and `exclude_half.life` may be in +#' use for the same interval. +#' @param exclude_half.life An optional logical vector (one value per +#' concentration measurement) of points to exclude from the half-life +#' calculation; the remaining points use the usual curve-stripping selection. +#' `TRUE`/`FALSE`/`NA` and the "in use" rule are interpreted as for +#' `include_half.life`. #' @param lloq An optional scalar or vector (the same length as `conc`) with the #' lower limit of quantification passed to [pk.calc.half.life()] for the Tobit #' half-life method. diff --git a/man/PKNCAconc.Rd b/man/PKNCAconc.Rd index 3f1f970a..b312a7ac 100644 --- a/man/PKNCAconc.Rd +++ b/man/PKNCAconc.Rd @@ -75,7 +75,12 @@ used for urine or feces measurements.} name in the dataset of the points to exclude from the half-life calculation (still using normal curve-stripping selection rules for the other points) or to include for the half-life (using specifically those points and -bypassing automatic curve-stripping point selection). See the "Half-Life +bypassing automatic curve-stripping point selection). The column is logical +with three meaningful states per point: \code{TRUE} acts on the point, \code{FALSE} +does not, and \code{NA} is undefined. A column is treated as "in use" for an +interval unless it is entirely \code{NA}, so leave it \code{NA} (rather than \code{FALSE}) +where the mechanism should not apply. Only one of \code{exclude_half.life} and +\code{include_half.life} may be in use for a given interval. See the "Half-Life Calculation" vignette for more details on the use of these arguments.} \item{lloq}{(optional) The lower limit of quantification used by the Tobit diff --git a/man/pk.nca.interval.Rd b/man/pk.nca.interval.Rd index 003a9994..0416fa71 100644 --- a/man/pk.nca.interval.Rd +++ b/man/pk.nca.interval.Rd @@ -70,12 +70,20 @@ bolus and nonzero for intravascular infusion)} \item{impute_method}{The method to use for imputation as a character string} -\item{include_half.life}{An optional boolean vector of the concentration -measurements to include in the half-life calculation. If given, no -half-life point selection will occur.} - -\item{exclude_half.life}{An optional boolean vector of the concentration -measurements to exclude from the half-life calculation.} +\item{include_half.life}{An optional logical vector (one value per +concentration measurement) of points to include in the half-life +calculation. If in use, automatic half-life point selection does not occur +and exactly the \code{TRUE} points are used. \code{TRUE} includes a point, \code{FALSE} +does not, and \code{NA} is undefined; the vector is "in use" for the interval +unless it is entirely \code{NA} (so an all-\code{FALSE} vector still counts as in +use). At most one of \code{include_half.life} and \code{exclude_half.life} may be in +use for the same interval.} + +\item{exclude_half.life}{An optional logical vector (one value per +concentration measurement) of points to exclude from the half-life +calculation; the remaining points use the usual curve-stripping selection. +\code{TRUE}/\code{FALSE}/\code{NA} and the "in use" rule are interpreted as for +\code{include_half.life}.} \item{lloq}{An optional scalar or vector (the same length as \code{conc}) with the lower limit of quantification passed to \code{\link[=pk.calc.half.life]{pk.calc.half.life()}} for the Tobit diff --git a/vignettes/v06-half-life-calculation.Rmd b/vignettes/v06-half-life-calculation.Rmd index b7de0e30..93be48c0 100644 --- a/vignettes/v06-half-life-calculation.Rmd +++ b/vignettes/v06-half-life-calculation.Rmd @@ -88,6 +88,13 @@ exclusion is applied (the interval is treated as-is, like the argument had not been given). If some values are `NA` for the interval, those are treated as `FALSE`. +A column counts as in use for an interval whenever it contains any non-`NA` +value, even if every value is `FALSE`. Only one of `exclude_half.life` and +`include_half.life` may be in use for the same interval; supplying both raises +the error "Cannot both include and exclude half-life points for the same +interval". For this reason, initialize these columns to `NA` (rather than +`FALSE`) when the corresponding method is not being used. + ## Exclusion of Specific Points with Curve Stripping In some cases, specific points will be known outliers, or there may be another reason to exclude specific points. And, with those points excluded, the half-life should be calculated using the normal curve stripping methods described above. @@ -121,14 +128,14 @@ as.data.frame(result_obj_exclude1) In other cases, the exact points to use for half-life calculation are known, and automatic point selection with curve stripping should not be performed. -To exclude specific points but otherwise use curve stripping, use the `include_half.life` option as the column name in the concentration dataset for `PKNCAconc()` as illustrated below. +To use only specific points and bypass automatic curve stripping, use the `include_half.life` option as the column name in the concentration dataset for `PKNCAconc()` as illustrated below. ```{r include-points} data_conc$include_hl <- data_conc$Time > 3 -# Confirm that we will be excluding exactly one point +# Confirm that we will be including exactly six points stopifnot(sum(data_conc$include_hl) == 6) -# Drop one point +# Use only these points for the half-life conc_obj_include6 <- PKNCAconc( data_conc, From af4bc661eadf7546162c70c1e835413a3b460b8f Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Sat, 13 Jun 2026 22:52:30 +0000 Subject: [PATCH 2/2] docs: sharpen curve-stripping wording for include/exclude_half.life Make explicit that exclude_half.life does NOT bypass automatic curve-stripping point selection -- it drops the flagged points, and curve stripping still runs on the remaining points -- while include_half.life bypasses curve stripping and names the exact points to use. Replace the generic "TRUE acts on the point" phrasing with the per-column meaning (TRUE uses/excludes the point). Co-Authored-By: Claude Opus 4.8 --- R/class-PKNCAconc.R | 20 ++++++++++---------- R/pk.calc.all.R | 23 ++++++++++++----------- man/PKNCAconc.Rd | 20 ++++++++++---------- man/pk.nca.interval.Rd | 23 ++++++++++++----------- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/R/class-PKNCAconc.R b/R/class-PKNCAconc.R index ee34f629..e6348da2 100644 --- a/R/class-PKNCAconc.R +++ b/R/class-PKNCAconc.R @@ -28,16 +28,16 @@ #' @param duration (optional) The duration of collection as is typically used #' for concentration measurements in urine or feces. #' @param exclude_half.life,include_half.life A character scalar for the column -#' name in the dataset of the points to exclude from the half-life calculation -#' (still using normal curve-stripping selection rules for the other points) -#' or to include for the half-life (using specifically those points and -#' bypassing automatic curve-stripping point selection). The column is logical -#' with three meaningful states per point: `TRUE` acts on the point, `FALSE` -#' does not, and `NA` is undefined. A column is treated as "in use" for an -#' interval unless it is entirely `NA`, so leave it `NA` (rather than `FALSE`) -#' where the mechanism should not apply. Only one of `exclude_half.life` and -#' `include_half.life` may be in use for a given interval. See the "Half-Life -#' Calculation" vignette for more details on the use of these arguments. +#' name in the dataset. `exclude_half.life` names points to drop; automatic +#' curve-stripping point selection is still performed on the remaining +#' (non-excluded) points and is not bypassed. `include_half.life` names the +#' exact points to use, bypassing automatic curve-stripping point selection. +#' Each value is `TRUE`, `FALSE`, or `NA` (undefined); a column is treated as +#' "in use" for an interval unless it is entirely `NA`, so leave it `NA` +#' (rather than `FALSE`) where the mechanism should not apply. Only one of +#' `exclude_half.life` and `include_half.life` may be in use for a given +#' interval. See the "Half-Life Calculation" vignette for more details on the +#' use of these arguments. #' @param lloq (optional) The lower limit of quantification used by the Tobit #' half-life method (`hl_method = "tobit"`). Either the name of a column in #' `data` giving the per-observation LLOQ or a numeric scalar applied to all diff --git a/R/pk.calc.all.R b/R/pk.calc.all.R index 24417c66..db3a76d5 100644 --- a/R/pk.calc.all.R +++ b/R/pk.calc.all.R @@ -352,18 +352,19 @@ pk.nca.intervals <- function(data_conc, data_dose, data_intervals, sparse, #' @param interval One row of an interval definition (see #' [check.interval.specification()] for how to define the interval. #' @param include_half.life An optional logical vector (one value per -#' concentration measurement) of points to include in the half-life -#' calculation. If in use, automatic half-life point selection does not occur -#' and exactly the `TRUE` points are used. `TRUE` includes a point, `FALSE` -#' does not, and `NA` is undefined; the vector is "in use" for the interval -#' unless it is entirely `NA` (so an all-`FALSE` vector still counts as in -#' use). At most one of `include_half.life` and `exclude_half.life` may be in -#' use for the same interval. +#' concentration measurement) naming the points to use for the half-life. If +#' in use, automatic curve-stripping point selection is bypassed and exactly +#' the `TRUE` points are used for the half-life regression. `TRUE` uses the +#' point, `FALSE` does not, and `NA` is undefined; the vector is "in use" for +#' the interval unless it is entirely `NA` (so an all-`FALSE` vector still +#' counts as in use). At most one of `include_half.life` and +#' `exclude_half.life` may be in use for the same interval. #' @param exclude_half.life An optional logical vector (one value per -#' concentration measurement) of points to exclude from the half-life -#' calculation; the remaining points use the usual curve-stripping selection. -#' `TRUE`/`FALSE`/`NA` and the "in use" rule are interpreted as for -#' `include_half.life`. +#' concentration measurement) naming points to drop before point selection. +#' Automatic curve-stripping point selection is still performed (it is not +#' bypassed) on the remaining, non-excluded points. `TRUE` excludes the point, +#' `FALSE` does not, and `NA` is undefined; the "in use" rule is the same as +#' for `include_half.life`. #' @param lloq An optional scalar or vector (the same length as `conc`) with the #' lower limit of quantification passed to [pk.calc.half.life()] for the Tobit #' half-life method. diff --git a/man/PKNCAconc.Rd b/man/PKNCAconc.Rd index b312a7ac..3381f47d 100644 --- a/man/PKNCAconc.Rd +++ b/man/PKNCAconc.Rd @@ -72,16 +72,16 @@ for concentration measurements in urine or feces.} used for urine or feces measurements.} \item{exclude_half.life, include_half.life}{A character scalar for the column -name in the dataset of the points to exclude from the half-life calculation -(still using normal curve-stripping selection rules for the other points) -or to include for the half-life (using specifically those points and -bypassing automatic curve-stripping point selection). The column is logical -with three meaningful states per point: \code{TRUE} acts on the point, \code{FALSE} -does not, and \code{NA} is undefined. A column is treated as "in use" for an -interval unless it is entirely \code{NA}, so leave it \code{NA} (rather than \code{FALSE}) -where the mechanism should not apply. Only one of \code{exclude_half.life} and -\code{include_half.life} may be in use for a given interval. See the "Half-Life -Calculation" vignette for more details on the use of these arguments.} +name in the dataset. \code{exclude_half.life} names points to drop; automatic +curve-stripping point selection is still performed on the remaining +(non-excluded) points and is not bypassed. \code{include_half.life} names the +exact points to use, bypassing automatic curve-stripping point selection. +Each value is \code{TRUE}, \code{FALSE}, or \code{NA} (undefined); a column is treated as +"in use" for an interval unless it is entirely \code{NA}, so leave it \code{NA} +(rather than \code{FALSE}) where the mechanism should not apply. Only one of +\code{exclude_half.life} and \code{include_half.life} may be in use for a given +interval. See the "Half-Life Calculation" vignette for more details on the +use of these arguments.} \item{lloq}{(optional) The lower limit of quantification used by the Tobit half-life method (\code{hl_method = "tobit"}). Either the name of a column in diff --git a/man/pk.nca.interval.Rd b/man/pk.nca.interval.Rd index 0416fa71..6325bba2 100644 --- a/man/pk.nca.interval.Rd +++ b/man/pk.nca.interval.Rd @@ -71,19 +71,20 @@ bolus and nonzero for intravascular infusion)} \item{impute_method}{The method to use for imputation as a character string} \item{include_half.life}{An optional logical vector (one value per -concentration measurement) of points to include in the half-life -calculation. If in use, automatic half-life point selection does not occur -and exactly the \code{TRUE} points are used. \code{TRUE} includes a point, \code{FALSE} -does not, and \code{NA} is undefined; the vector is "in use" for the interval -unless it is entirely \code{NA} (so an all-\code{FALSE} vector still counts as in -use). At most one of \code{include_half.life} and \code{exclude_half.life} may be in -use for the same interval.} +concentration measurement) naming the points to use for the half-life. If +in use, automatic curve-stripping point selection is bypassed and exactly +the \code{TRUE} points are used for the half-life regression. \code{TRUE} uses the +point, \code{FALSE} does not, and \code{NA} is undefined; the vector is "in use" for +the interval unless it is entirely \code{NA} (so an all-\code{FALSE} vector still +counts as in use). At most one of \code{include_half.life} and +\code{exclude_half.life} may be in use for the same interval.} \item{exclude_half.life}{An optional logical vector (one value per -concentration measurement) of points to exclude from the half-life -calculation; the remaining points use the usual curve-stripping selection. -\code{TRUE}/\code{FALSE}/\code{NA} and the "in use" rule are interpreted as for -\code{include_half.life}.} +concentration measurement) naming points to drop before point selection. +Automatic curve-stripping point selection is still performed (it is not +bypassed) on the remaining, non-excluded points. \code{TRUE} excludes the point, +\code{FALSE} does not, and \code{NA} is undefined; the "in use" rule is the same as +for \code{include_half.life}.} \item{lloq}{An optional scalar or vector (the same length as \code{conc}) with the lower limit of quantification passed to \code{\link[=pk.calc.half.life]{pk.calc.half.life()}} for the Tobit