diff --git a/NEWS.md b/NEWS.md index 630a456d..9dd40181 100644 --- a/NEWS.md +++ b/NEWS.md @@ -29,8 +29,6 @@ the dosing including dose amount and route. `summary()` (#477) * New post-processing functions to normalize PKNCA result parameters based on any column in PKNCAconc data.frame (`normalize_by_col()`) or by using a custom normalization table (`normalize()`) -* New excretion rate parameters: `ermax` (Maximum excretion rate), `ertmax` (Midpoint time - of maximum excretion rate) and `ertlst` (Time of last excretion rate measurement) (#433) # PKNCA 0.12.1 diff --git a/R/001-add.interval.col.R b/R/001-add.interval.col.R index 908d3192..076fee9e 100644 --- a/R/001-add.interval.col.R +++ b/R/001-add.interval.col.R @@ -114,9 +114,9 @@ add.interval.col <- function(name, choices=c( "unitless", "fraction", "%", "count", "time", "inverse_time", - "amount", "amount_dose", "amount_time", + "amount", "amount_dose", "conc", "conc_dosenorm", - "dose", + "dose", "volume", "auc", "aumc", "auc_dosenorm", "aumc_dosenorm", diff --git a/R/auc_integrate.R b/R/auc_integrate.R index 15b4a979..336db5ec 100644 --- a/R/auc_integrate.R +++ b/R/auc_integrate.R @@ -183,48 +183,3 @@ auc_integrate <- function(conc, time, clast, tlast, lambda.z, interval_method, f ret <- sum(ret) ret } - -#' Support function for AUMC integration (reuses the same interval_method logic as AUC) -#' -#' @inheritParams auc_integrate -#' @param fun_linear Linear trapezoidal rule for t×conc (AUMC) -#' @param fun_log Log trapezoidal rule for t×conc (AUMC) -#' @param fun_inf Analytical extrapolation to infinity for AUMC -#' -#' @details -#' This function works identically to `auc_integrate()`, but integrates -#' the first moment curve (t × conc) instead of conc. -#' The `interval_method` vector from `choose_interval_method()` is reused directly. -#' -#' @returns The numeric value of the AUMC -#' @keywords internal -aumc_integrate <- function(conc, time, clast, tlast, lambda.z, interval_method, - fun_linear, fun_log, fun_inf) { - assert_lambdaz(lambda.z = lambda.z) - - interval_method_within <- interval_method[-length(interval_method)] - interval_method_extrap <- interval_method[length(interval_method)] - - idx_1 <- seq_len(length(conc) - 1) - idx_1_linear <- idx_1[interval_method_within == "linear"] - idx_1_log <- idx_1[interval_method_within == "log"] - - ret <- - c( - fun_linear(conc[idx_1_linear], conc[idx_1_linear + 1], - time[idx_1_linear], time[idx_1_linear + 1]), - fun_log(conc[idx_1_log], conc[idx_1_log + 1], - time[idx_1_log], time[idx_1_log + 1]) - ) - - if (interval_method_extrap %in% "extrap_log") { - # Whether AUMCinf,obs or AUMCinf,pred is calculated depends on if clast,obs - # or clast,pred is passed in. - ret[length(ret)+1] <- fun_inf(clast, tlast, lambda.z) - } else if (interval_method_extrap != "zero") { - stop("Invalid interval_method_extrap in aumc_integrate, please report a bug: ", interval_method_extrap) # nocov - } - - ret <- sum(ret) - ret -} diff --git a/R/aucint.R b/R/aucint.R index d739a05b..b8aebf86 100644 --- a/R/aucint.R +++ b/R/aucint.R @@ -356,323 +356,3 @@ PKNCA.set.summary( point=business.geomean, spread=business.geocv ) - - -#' Calculate the AUMC over an interval with interpolation and/or -#' extrapolation of concentrations for the beginning and end of the -#' interval. -#' -#' @details -#' When `pk.calc.aumcint()` needs to extrapolate using `lambda.z` (in other -#' words, using the half-life), it will always extrapolate using the logarithmic -#' trapezoidal rule to align with using a half-life calculation for the -#' extrapolation. -#' -#' @inheritParams pk.calc.aucint -#' @family AUMC calculations -#' @returns The AUMC for an interval of time as a number -#' @export -pk.calc.aumcint <- function(conc, time, - interval=NULL, start=NULL, end=NULL, - clast=pk.calc.clast.obs(conc, time), - lambda.z=NA, - time.dose=NULL, - route="extravascular", - duration.dose=0, - method=NULL, - auc.type="AUClast", - conc.blq=NULL, - conc.na=NULL, - check=TRUE, - ..., - options=list()) { - # Check inputs - method <- PKNCA.choose.option(name="auc.method", value=method, options=options) - if (check) { - assert_conc_time(conc, time) - data <- - clean.conc.blq( - conc = conc, time = time, - conc.blq = conc.blq, conc.na = conc.na, options = options, - check = FALSE - ) - } else { - data <- data.frame(conc, time) - } - if (all(data$conc %in% 0)) { - return(structure(0, exclude = "DO NOT EXCLUDE")) - } - interval <- assert_intervaltime_single(interval = interval, start = start, end = end) - missing_times <- - if (is.infinite(interval[2])) { - setdiff(c(interval[1], time.dose), data$time) - } else { - setdiff(c(interval, time.dose), data$time) - } - # Handle the potential double-calculation (before/after tlast) with AUMCinf - conc_clast <- NULL - time_clast <- NULL - if (auc.type %in% "AUCinf") { - tlast <- pk.calc.tlast(conc=data$conc, time=data$time) - clast_obs <- pk.calc.clast.obs(conc=data$conc, time=data$time) - if (is.na(clast) && is.na(lambda.z)) { - # clast.pred is NA likely because the half-life was not calculable - return(structure(NA_real_, exclude = "clast.pred is NA because the half-life is NA")) - } else if (is.na(clast)) { - stop("Please report a bug. clast is NA and the half-life is not NA") # nocov - } else if (clast != clast_obs & interval[2] > tlast) { - # If using clast.pred, we need to doubly calculate at tlast. - conc_clast <- clast - time_clast <- tlast - } - } - extrap_times <- numeric() - if (length(missing_times) > 0) { - if (is.null(time.dose)) { - missing_conc <- - interp.extrap.conc( - conc = data$conc, time = data$time, - time.out = missing_times, - method = method, - auc.type = auc.type, - clast = clast, - lambda.z = lambda.z, - options = options, - ... - ) - } else { - missing_conc <- - interp.extrap.conc.dose( - conc = data$conc, time = data$time, - time.out = missing_times, - method = method, - auc.type = auc.type, - clast = clast, lambda.z = lambda.z, - options = options, - # arguments specific to interp.extrap.conc.dose - time.dose = time.dose, - route.dose = route, - duration.dose = duration.dose, - out.after = FALSE, - ... - ) - } - new_data <- data.frame(conc=c(data$conc, conc_clast, missing_conc), - time=c(data$time, time_clast, missing_times)) - tlast <- pk.calc.tlast(conc = data$conc, time = data$time, check = FALSE) - extrap_times <- missing_times[missing_times > tlast] - new_data <- new_data[new_data$time >= interval[1] & - new_data$time <= interval[2],] - new_data <- new_data[order(new_data$time),] - conc_interp <- new_data$conc - time_interp <- new_data$time - if (any(mask_na_conc <- is.na(conc_interp))) { - missing_times <- time_interp[mask_na_conc] - warning_message <- - if (any(is.na(lambda.z))) { - paste("Some interpolated/extrapolated concentration values are missing", - "(may be due to interpolating or extrapolating over a dose with lambda.z=NA).", - "Time points with missing data are: ", - paste(missing_times, collapse=", ")) - } else { - paste("Some interpolated/extrapolated concentration values are missing", - "Time points with missing data are: ", - paste(missing_times, collapse=", ")) - } - warning(warning_message) - return(NA_real_) - } - } else { - mask_time <- data$time >= interval[1] & data$time <= interval[2] - conc_interp <- data$conc[mask_time] - time_interp <- data$time[mask_time] - } - # AUMCinf traces an AUMClast curve if the interval is finite (because - # the interval doesn't go to infinity) while AUMCall and AUMClast trace - # their own curves. Or, they all trace their own curves. - auc.type_map <- - if (is.infinite(interval[2])) { - list( - AUClast="AUClast", - AUCall="AUCall", - AUCinf="AUCinf" - )[[auc.type]] - } else { - list( - AUClast="AUClast", - AUCall="AUCall", - AUCinf="AUClast" - )[[auc.type]] - } - - interval_method <- - choose_interval_method( - conc = conc_interp, - time = time_interp, - tlast = max(time_interp), - method = method, - auc.type = auc.type, - options = options - ) - if (is.finite(interval[2])) { - interval_method[length(interval_method)] <- "zero" - } - if (length(extrap_times) > 0) { - interval_method[which(time_interp == extrap_times) - 1] <- "log" - } - ret <- - aumc_integrate( - conc = conc_interp, time = time_interp, - clast = clast, tlast = tlast, lambda.z = lambda.z, - interval_method = interval_method, - fun_linear = aumcintegrate_linear, - fun_log = aumcintegrate_log, - fun_inf = aumcintegrate_inf - ) - ret -} - -#' @describeIn pk.calc.aumcint Interpolate or extrapolate concentrations for -#' AUMClast -#' @export -pk.calc.aumcint.last <- function(conc, time, start=NULL, end=NULL, time.dose, ..., options=list()) { - if (missing(time.dose)) - time.dose <- NULL - pk.calc.aumcint(conc=conc, time=time, - start=start, end=end, - options=options, - time.dose=time.dose, - ..., - auc.type="AUClast") -} - -#' @describeIn pk.calc.aumcint Interpolate or extrapolate concentrations for -#' AUMCall -#' @export -pk.calc.aumcint.all <- function(conc, time, start=NULL, end=NULL, time.dose, ..., options=list()) { - if (missing(time.dose)) - time.dose <- NULL - pk.calc.aumcint(conc=conc, time=time, - start=start, end=end, - options=options, - time.dose=time.dose, - ..., - auc.type="AUCall") -} - -#' @describeIn pk.calc.aumcint Interpolate or extrapolate concentrations for -#' AUMCinf.obs -#' @export -pk.calc.aumcint.inf.obs <- function(conc, time, start=NULL, end=NULL, time.dose, lambda.z, clast.obs, ..., options=list()) { - if (missing(time.dose)) - time.dose <- NULL - pk.calc.aumcint(conc=conc, time=time, - start=start, end=end, - time.dose=time.dose, - lambda.z=lambda.z, clast=clast.obs, - options=options, ..., - auc.type="AUCinf") -} - -#' @describeIn pk.calc.aumcint Interpolate or extrapolate concentrations for -#' AUMCinf.pred -#' @export -pk.calc.aumcint.inf.pred <- function(conc, time, start=NULL, end=NULL, time.dose, lambda.z, clast.pred, ..., options=list()) { - if (missing(time.dose)) - time.dose <- NULL - pk.calc.aumcint(conc=conc, time=time, - start=start, end=end, - time.dose=time.dose, - lambda.z=lambda.z, clast=clast.pred, - options=options, ..., - auc.type="AUCinf") -} - - -# aumcint.last (without dose awareness) -add.interval.col("aumcint.last", - FUN="pk.calc.aumcint.last", - values=c(FALSE, TRUE), - unit_type="aumc", - pretty_name="AUMCint (based on AUMClast extrapolation)", - desc="The area under the moment curve in the interval extrapolating from Tlast to infinity with zeros (matching AUMClast)", - formalsmap=list(conc="conc.group", time="time.group", time.dose=NULL)) - -# aumcint.last.dose (WITH dose awareness) -add.interval.col("aumcint.last.dose", - FUN="pk.calc.aumcint.last", - values=c(FALSE, TRUE), - unit_type="aumc", - pretty_name="AUMCint (based on AUMClast extrapolation, dose-aware)", - desc="The area under the moment curve in the interval extrapolating from Tlast to infinity with zeros (matching AUMClast) with dose-aware interpolation/extrapolation of concentrations", - formalsmap=list(conc="conc.group", time="time.group", time.dose="time.dose.group")) - -# aumcint.all (without dose awareness) -add.interval.col("aumcint.all", - FUN="pk.calc.aumcint.all", - values=c(FALSE, TRUE), - unit_type="aumc", - pretty_name="AUMCint (based on AUMCall extrapolation)", - desc="The area under the moment curve in the interval extrapolating from Tlast to infinity with the triangle from Tlast to the next point and zero thereafter (matching AUMCall)", - formalsmap=list(conc="conc.group", time="time.group", time.dose=NULL)) - -# aumcint.all.dose (WITH dose awareness) -add.interval.col("aumcint.all.dose", - FUN="pk.calc.aumcint.all", - values=c(FALSE, TRUE), - unit_type="aumc", - pretty_name="AUMCint (based on AUMCall extrapolation, dose-aware)", - desc="The area under the moment curve in the interval extrapolating from Tlast to infinity with the triangle from Tlast to the next point and zero thereafter (matching AUMCall) with dose-aware interpolation/extrapolation of concentrations", - formalsmap=list(conc="conc.group", time="time.group", time.dose="time.dose.group")) - -# aumcint.inf.obs (without dose awareness) -add.interval.col("aumcint.inf.obs", - FUN="pk.calc.aumcint.inf.obs", - values=c(FALSE, TRUE), - unit_type="aumc", - pretty_name="AUMCint (based on AUMCinf,obs extrapolation)", - desc="The area under the moment curve in the interval extrapolating from Tlast to infinity with zeros (matching AUMClast)", - formalsmap=list(conc="conc.group", time="time.group", time.dose=NULL), - depends=c("lambda.z", "clast.obs")) - -# aumcint.inf.obs.dose (WITH dose awareness) -add.interval.col("aumcint.inf.obs.dose", - FUN="pk.calc.aumcint.inf.obs", - values=c(FALSE, TRUE), - unit_type="aumc", - pretty_name="AUMCint (based on AUMCinf,obs extrapolation, dose-aware)", - desc="The area under the moment curve in the interval extrapolating from Tlast to infinity with zeros (matching AUMClast) with dose-aware interpolation/extrapolation of concentrations", - formalsmap=list(conc="conc.group", time="time.group", time.dose="time.dose.group"), - depends=c("lambda.z", "clast.obs")) - -# aumcint.inf.pred (without dose awareness) -add.interval.col("aumcint.inf.pred", - FUN="pk.calc.aumcint.inf.pred", - values=c(FALSE, TRUE), - unit_type="aumc", - pretty_name="AUMCint (based on AUMCinf,pred extrapolation)", - desc="The area under the moment curve in the interval extrapolating from Tlast to infinity with the triangle from Tlast to the next point and zero thereafter (matching AUMCall)", - formalsmap=list(conc="conc.group", time="time.group", time.dose=NULL), - depends=c("lambda.z", "clast.pred")) - -# aumcint.inf.pred.dose (WITH dose awareness) -add.interval.col("aumcint.inf.pred.dose", - FUN="pk.calc.aumcint.inf.pred", - values=c(FALSE, TRUE), - unit_type="aumc", - pretty_name="AUMCint (based on AUMCinf,pred extrapolation, dose-aware)", - desc="The area under the moment curve in the interval extrapolating from Tlast to infinity with the triangle from Tlast to the next point and zero thereafter (matching AUMCall) with dose-aware interpolation/extrapolation of concentrations", - formalsmap=list(conc="conc.group", time="time.group", time.dose="time.dose.group"), - depends=c("lambda.z", "clast.pred")) - -PKNCA.set.summary( - name = c( - "aumcint.last", "aumcint.last.dose", - "aumcint.all", "aumcint.all.dose", - "aumcint.inf.obs", "aumcint.inf.obs.dose", - "aumcint.inf.pred", "aumcint.inf.pred.dose" - ), - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv -) \ No newline at end of file diff --git a/R/auciv.R b/R/auciv.R index fb870b1d..a99c1a52 100644 --- a/R/auciv.R +++ b/R/auciv.R @@ -198,124 +198,3 @@ PKNCA.set.summary( point=business.mean, spread=business.sd ) - - -#' Calculate AUMC for intravenous dosing with C0 back-extrapolation -#' -#' @details Analogous to pk.calc.auciv but for AUMC. -#' Replaces the first AUMC interval (from measured C0) with one using extrapolated c0. -#' -#' @inheritParams pk.calc.auxc -#' @param c0 The concentration at time 0 (extrapolated) -#' @param aumc The AUMC calculated without c0 adjustment (e.g., aumcall, aumclast) -#' @return The AUMC with IV back-extrapolation applied -#' @export -pk.calc.aumciv <- function(conc, time, c0, aumc, ..., options = list(), check = TRUE) { - if (check) { - assert_conc_time(conc = conc, time = time) - data <- clean.conc.blq(conc, time, options = options, check = FALSE) - } else { - data <- data.frame(conc = conc, time = time) - } - - if (!(0 %in% time)) { - return(structure(NA_real_, exclude = "No time 0 in data")) - } else if (is.na(c0)) { - return(structure(NA_real_, exclude = "c0 is not calculated")) - } - - # AUMC for first interval using measured concentrations - aumc_first <- pk.calc.aumc.last( - conc = data$conc[1:2], - time = data$time[1:2], - ..., - check = FALSE - ) - - # AUMC for first interval using extrapolated c0 - aumc_second <- pk.calc.aumc.last( - conc = c(c0, data$conc[2]), - time = data$time[1:2], - ..., - check = FALSE - ) - - aumc_final <- aumc + aumc_second - aumc_first - aumc_final -} - -# Register all standard AUMC IV versions -add.interval.col( - name = "aumcivlast", - FUN = "pk.calc.aumciv", - unit_type = "aumc", - pretty_name = "AUMClast (IV dosing)", - depends = c("aumclast", "c0"), - desc = "AUMClast with back-extrapolation using extrapolated C0 for IV dosing", - sparse = FALSE, - formalsmap = list(aumc = "aumclast") -) - -add.interval.col( - name = "aumcivall", - FUN = "pk.calc.aumciv", - unit_type = "aumc", - pretty_name = "AUMCall (IV dosing)", - depends = c("aumcall", "c0"), - desc = "AUMCall with back-extrapolation using extrapolated C0 for IV dosing", - sparse = FALSE, - formalsmap = list(aumc = "aumcall") -) - -add.interval.col( - name = "aumcivint.last", - FUN = "pk.calc.aumciv", - unit_type = "aumc", - pretty_name = "AUMCint,last (IV dosing)", - depends = c("aumcint.last", "c0"), - desc = "The AUMCint,last calculated with back-extrapolation for intravenous dosing using extrapolated C0", - sparse = FALSE, - formalsmap = list(aumc = "aumcint.last") -) - -add.interval.col( - name = "aumcivint.all", - FUN = "pk.calc.aumciv", - unit_type = "aumc", - pretty_name = "AUMCint,all (IV dosing)", - depends = c("aumcint.all", "c0"), - desc = "The AUMCint,all calculated with back-extrapolation for intravenous dosing using extrapolated C0", - sparse = FALSE, - formalsmap = list(aumc = "aumcint.all") -) - -add.interval.col( - name = "aumcivinf.obs", - FUN = "pk.calc.aumciv", - unit_type = "aumc", - pretty_name = "AUMCinf,obs (IV dosing)", - depends = c("aumcinf.obs", "c0"), - desc = "AUMCinf,obs with back-extrapolation using extrapolated C0", - sparse = FALSE, - formalsmap = list(aumc = "aumcinf.obs") -) - -add.interval.col( - name = "aumcivinf.pred", - FUN = "pk.calc.aumciv", - unit_type = "aumc", - pretty_name = "AUMCinf,pred (IV dosing)", - depends = c("aumcinf.pred", "c0"), - desc = "AUMCinf,pred with back-extrapolation using extrapolated C0", - sparse = FALSE, - formalsmap = list(aumc = "aumcinf.pred") -) - - -PKNCA.set.summary( - name = c("aumcivlast", "aumcivall", "aumcivinf.obs", "aumcivinf.pred", - "aumcivint.last", "aumcivint.all"), - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv -) \ No newline at end of file diff --git a/R/pk.calc.simple.R b/R/pk.calc.simple.R index 03d10d5d..b0992c90 100644 --- a/R/pk.calc.simple.R +++ b/R/pk.calc.simple.R @@ -440,7 +440,12 @@ add.interval.col("kel.obs", desc="Elimination rate (as calculated from the MRT with observed Clast)", formalsmap=list(mrt="mrt.obs"), depends="mrt.obs") - +PKNCA.set.summary( + name="kel.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("kel.pred", FUN="pk.calc.kel", values=c(FALSE, TRUE), @@ -449,7 +454,12 @@ add.interval.col("kel.pred", desc="Elimination rate (as calculated from the MRT with predicted Clast)", formalsmap=list(mrt="mrt.pred"), depends="mrt.pred") - +PKNCA.set.summary( + name="kel.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("kel.last", FUN="pk.calc.kel", values=c(FALSE, TRUE), @@ -458,7 +468,12 @@ add.interval.col("kel.last", desc="Elimination rate (as calculated from the MRT using AUClast)", formalsmap=list(mrt="mrt.last"), depends="mrt.last") - +PKNCA.set.summary( + name="kel.last", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("kel.iv.obs", FUN="pk.calc.kel", values=c(FALSE, TRUE), @@ -467,7 +482,12 @@ add.interval.col("kel.iv.obs", desc="Elimination rate (as calculated from the intravenous MRTobs)", formalsmap=list(mrt="mrt.iv.obs"), depends="mrt.iv.obs") - +PKNCA.set.summary( + name="kel.iv.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("kel.iv.pred", FUN="pk.calc.kel", values=c(FALSE, TRUE), @@ -476,7 +496,12 @@ add.interval.col("kel.iv.pred", desc="Elimination rate (as calculated from the intravenous MRTpred)", formalsmap=list(mrt="mrt.iv.pred"), depends="mrt.iv.pred") - +PKNCA.set.summary( + name="kel.iv.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("kel.iv.last", FUN="pk.calc.kel", values=c(FALSE, TRUE), @@ -485,100 +510,11 @@ add.interval.col("kel.iv.last", desc="Elimination rate (as calculated from the intravenous MRTlast)", formalsmap=list(mrt="mrt.iv.last"), depends="mrt.iv.last") -add.interval.col("kel.all", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (based on AUCall)", - desc = "Elimination rate (as calculated from the MRTall)", - formalsmap = list(mrt = "mrt.all"), - depends = "mrt.all") - -add.interval.col("kel.int.all", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (based on AUCint.all)", - desc = "Elimination rate (as calculated from the MRTint.all)", - formalsmap = list(mrt = "mrt.int.all"), - depends = "mrt.int.all") - -add.interval.col("kel.int.inf.obs", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (based on AUCint.inf.obs)", - desc = "Elimination rate (as calculated from the MRTint.inf.obs)", - formalsmap = list(mrt = "mrt.int.inf.obs"), - depends = "mrt.int.inf.obs") - -add.interval.col("kel.int.inf.pred", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (based on AUCint.inf.pred)", - desc = "Elimination rate (as calculated from the MRTint.inf.pred)", - formalsmap = list(mrt = "mrt.int.inf.pred"), - depends = "mrt.int.inf.pred") - -add.interval.col("kel.int.last", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (based on AUCint.last)", - desc = "Elimination rate (as calculated from the MRTint.last)", - formalsmap = list(mrt = "mrt.int.last"), - depends = "mrt.int.last") - -add.interval.col("kel.iv.all", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (for IV dosing, based on AUCall)", - desc = "Elimination rate (as calculated from the MRTiv.all))", - formalsmap = list(mrt = "mrt.iv.all"), - depends = "mrt.iv.all") - -add.interval.col("kel.ivint.all", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (IV dose interval, based on AUCint.all)", - desc = "Elimination rate (as calculated from the MRTivint.all)", - formalsmap = list(mrt = "mrt.ivint.all"), - depends = "mrt.ivint.all") - - -add.interval.col("kel.ivint.last", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (IV dose interval, based on AUCint.last)", - desc = "Elimination rate (as calculated from the MRTivint.last)", - formalsmap = list(mrt = "mrt.ivint.last"), - depends = "mrt.ivint.last") - -add.interval.col("kel.sparse.last", - FUN = "pk.calc.kel", - values = c(FALSE, TRUE), - unit_type = "inverse_time", - pretty_name = "Kel (for sparse data, based on AUClast)", - desc = "Elimination rate (as calculated from the MRTsparse.last)", - sparse = TRUE, - formalsmap = list(mrt = "mrt.sparse.last"), - depends = "mrt.sparse.last") - PKNCA.set.summary( - name = c( - # Elimination rate constant (kel) - "kel.obs", "kel.pred", "kel.last", "kel.iv.obs", "kel.iv.pred", "kel.iv.last", - "kel.all", "kel.int.all", "kel.int.inf.obs", "kel.int.inf.pred", "kel.int.last", - "kel.iv.all", "kel.ivint.all", "kel.ivint.last", - "kel.sparse.last" - ), - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv + name="kel.iv.last", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv ) #' Calculate the (observed oral) clearance @@ -620,7 +556,12 @@ add.interval.col("cl.last", desc="Clearance or observed oral clearance calculated to Clast", formalsmap=list(auc="auclast"), depends="auclast") - +PKNCA.set.summary( + name="cl.last", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("cl.all", FUN="pk.calc.cl", values=c(FALSE, TRUE), @@ -629,7 +570,12 @@ add.interval.col("cl.all", desc="Clearance or observed oral clearance calculated with AUCall", formalsmap=list(auc="aucall"), depends="aucall") - +PKNCA.set.summary( + name="cl.all", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("cl.obs", FUN="pk.calc.cl", values=c(FALSE, TRUE), @@ -638,7 +584,12 @@ add.interval.col("cl.obs", desc="Clearance or observed oral clearance calculated with observed Clast", formalsmap=list(auc="aucinf.obs"), depends="aucinf.obs") - +PKNCA.set.summary( + name="cl.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("cl.pred", FUN="pk.calc.cl", values=c(FALSE, TRUE), @@ -647,119 +598,11 @@ add.interval.col("cl.pred", desc="Clearance or observed oral clearance calculated with predicted Clast", formalsmap=list(auc="aucinf.pred"), depends="aucinf.pred") - -add.interval.col("cl.int.all", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (based on AUCint.all)", - desc = "Clearance or observed oral clearance calculated with AUCint.all", - formalsmap = list(auc = "aucint.all"), - depends = "aucint.all") - -add.interval.col("cl.int.inf.obs", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (based on AUCint.inf.obs)", - desc = "Clearance or observed oral clearance calculated with AUCint.inf.obs", - formalsmap = list(auc = "aucint.inf.obs"), - depends = "aucint.inf.obs") - -add.interval.col("cl.int.inf.pred", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (based on AUCint.inf.pred)", - desc = "Clearance or observed oral clearance calculated with AUCint.inf.pred", - formalsmap = list(auc = "aucint.inf.pred"), - depends = "aucint.inf.pred") - -add.interval.col("cl.int.last", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (based on AUCint.last)", - desc = "Clearance or observed oral clearance calculated with AUCint.last", - formalsmap = list(auc = "aucint.last"), - depends = "aucint.last") - -add.interval.col("cl.iv.all", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (for IV dosing, based on AUCall)", - desc = "Clearance for intravenous dosing calculated with AUCall", - formalsmap = list(auc = "aucivall"), - depends = "aucivall") - -add.interval.col("cl.iv.last", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (for IV dosing, based on AUClast)", - desc = "Clearance for intravenous dosing calculated with AUClast", - formalsmap = list(auc = "aucivlast"), - depends = "aucivlast") - -add.interval.col("cl.iv.obs", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (for IV dosing, based on AUCinf,obs)", - desc = "Clearance for intravenous dosing calculated with AUCinf,obs", - formalsmap = list(auc = "aucivinf.obs"), - depends = "aucivinf.obs") - -add.interval.col("cl.iv.pred", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (for IV dosing, based on AUCinf,pred)", - desc = "Clearance for intravenous dosing calculated with AUCinf,pred", - formalsmap = list(auc = "aucivinf.pred"), - depends = "aucivinf.pred") - -add.interval.col("cl.ivint.all", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (IV dose interval, based on AUCint.all)", - desc = "Clearance for intravenous dosing calculated with interval AUCint.all", - formalsmap = list(auc = "aucivint.all"), - depends = "aucivint.all") - -add.interval.col("cl.ivint.last", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (IV dose interval, based on AUCint.last)", - desc = "Clearance for intravenous dosing calculated with interval AUCint.last", - formalsmap = list(auc = "aucivint.last"), - depends = "aucivint.last") - -add.interval.col("cl.sparse.last", - FUN = "pk.calc.cl", - values = c(FALSE, TRUE), - unit_type = "clearance", - pretty_name = "CL (for sparse data, based on AUClast)", - desc = "Clearance from sparse sampling calculated with population AUClast", - sparse = TRUE, - formalsmap = list(auc = "sparse_auclast"), - depends = "sparse_auclast") - PKNCA.set.summary( - name = c( - # Clearance (observed, predicted, last, all, interpolated, IV, etc.) - "cl.last","cl.all", "cl.obs", "cl.pred", - "cl.int.all", "cl.int.inf.obs", "cl.int.inf.pred", "cl.int.last", - "cl.iv.all", "cl.iv.last", "cl.iv.obs", "cl.iv.pred", - "cl.ivint.all", "cl.ivint.last", - "cl.sparse.last" - ), - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv + name="cl.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv ) #' Calculate the absolute (or relative) bioavailability @@ -823,7 +666,12 @@ add.interval.col("mrt.obs", desc="The mean residence time to infinity using observed Clast", formalsmap=list(auc="aucinf.obs", aumc="aumcinf.obs"), depends=c("aucinf.obs", "aumcinf.obs")) - +PKNCA.set.summary( + name="mrt.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("mrt.pred", FUN="pk.calc.mrt", values=c(FALSE, TRUE), @@ -832,7 +680,12 @@ add.interval.col("mrt.pred", desc="The mean residence time to infinity using predicted Clast", formalsmap=list(auc="aucinf.pred", aumc="aumcinf.pred"), depends=c("aucinf.pred", "aumcinf.pred")) - +PKNCA.set.summary( + name="mrt.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("mrt.last", FUN="pk.calc.mrt", values=c(FALSE, TRUE), @@ -841,72 +694,11 @@ add.interval.col("mrt.last", desc="The mean residence time to the last observed concentration above the LOQ", formalsmap=list(auc="auclast", aumc="aumclast"), depends=c("auclast", "aumclast")) - -add.interval.col("mrt.all", - FUN = "pk.calc.mrt", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (based on AUCall)", - desc = "Mean residence time calculated with AUCall/AUMCall", - formalsmap = list(auc = "aucall", aumc = "aumcall"), - depends = c("aucall", "aumcall")) - -add.interval.col("mrt.int.all", - FUN = "pk.calc.mrt", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (based on AUCint.all)", - desc = "Mean residence time over interval calculated with AUCint.all/AUMCint.all", - formalsmap = list(auc = "aucint.all", aumc = "aumcint.all"), - depends = c("aucint.all", "aumcint.all")) - -add.interval.col("mrt.int.inf.obs", - FUN = "pk.calc.mrt", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (based on AUCint.inf.obs)", - desc = "Mean residence time over interval calculated with AUCint.inf.obs/AUMCint.inf.obs", - formalsmap = list(auc = "aucint.inf.obs", aumc = "aumcint.inf.obs"), - depends = c("aucint.inf.obs", "aumcint.inf.obs")) - -add.interval.col("mrt.int.inf.pred", - FUN = "pk.calc.mrt", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (based on AUCint.inf.pred)", - desc = "Mean residence time over interval calculated with AUCint.inf.pred/AUMCint.inf.pred", - formalsmap = list(auc = "aucint.inf.pred", aumc = "aumcint.inf.pred"), - depends = c("aucint.inf.pred", "aumcint.inf.pred")) - -add.interval.col("mrt.int.last", - FUN = "pk.calc.mrt", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (based on AUCint.last)", - desc = "Mean residence time over interval calculated with AUCint.last/AUMCint.last", - formalsmap = list(auc = "aucint.last", aumc = "aumcint.last"), - depends = c("aucint.last", "aumcint.last")) - -add.interval.col("mrt.sparse.last", - FUN = "pk.calc.mrt", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (for sparse data, based on AUClast)", - desc = "Mean residence time from sparse sampling", - sparse = TRUE, - formalsmap = list(auc = "sparse_auclast", aumc = "sparse_aumclast"), - depends = c("sparse_auclast", "sparse_aumclast")) - PKNCA.set.summary( - name = c( - # Mean residence time (MRT) - "mrt.obs", "mrt.pred", "mrt.last", "mrt.last", "mrt.all", - "mrt.int.all", "mrt.int.inf.obs", "mrt.int.inf.pred", "mrt.int.last", - "mrt.sparse.last" - ), - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv + name="mrt.last", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv ) #' @describeIn pk.calc.mrt MRT for an IV infusion @@ -928,7 +720,12 @@ add.interval.col("mrt.iv.obs", desc="The mean residence time to infinity using observed Clast correcting for dosing duration", formalsmap=list(auc="aucinf.obs", aumc="aumcinf.obs"), depends=c("aucinf.obs", "aumcinf.obs")) - +PKNCA.set.summary( + name="mrt.iv.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("mrt.iv.pred", FUN="pk.calc.mrt.iv", values=c(FALSE, TRUE), @@ -937,7 +734,12 @@ add.interval.col("mrt.iv.pred", desc="The mean residence time to infinity using predicted Clast correcting for dosing duration", formalsmap=list(auc="aucinf.pred", aumc="aumcinf.pred"), depends=c("aucinf.pred", "aumcinf.pred")) - +PKNCA.set.summary( + name="mrt.iv.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("mrt.iv.last", FUN="pk.calc.mrt.iv", values=c(FALSE, TRUE), @@ -946,43 +748,11 @@ add.interval.col("mrt.iv.last", desc="The mean residence time to the last observed concentration above the LOQ correcting for dosing duration", formalsmap=list(auc="auclast", aumc="aumclast"), depends=c("auclast", "aumclast")) - -add.interval.col("mrt.iv.all", - FUN = "pk.calc.mrt.iv", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (for IV dosing, based on AUCall)", - desc = "Mean residence time for IV dosing calculated with AUCall/AUMCall", - formalsmap = list(auc = "aucivall", aumc = "aumcivall"), - depends = c("aucivall", "aumcivall")) - -add.interval.col("mrt.ivint.all", - FUN = "pk.calc.mrt.iv", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (IV dose interval, based on AUCint.all)", - desc = "Mean residence time for IV interval calculated with AUCint.all/AUMCint.all", - formalsmap = list(auc = "aucivint.all", aumc = "aumcivint.all"), - depends = c("aucivint.all", "aumcivint.all")) - -add.interval.col("mrt.ivint.last", - FUN = "pk.calc.mrt.iv", - values = c(FALSE, TRUE), - unit_type = "time", - pretty_name = "MRT (IV dose interval, based on AUCint.last)", - desc = "Mean residence time for IV interval calculated with AUCint.last/AUMCint.last", - formalsmap = list(auc = "aucivint.last", aumc = "aumcivint.last"), - depends = c("aucivint.last", "aumcivint.last")) - PKNCA.set.summary( - name = c( - # Mean residence time (MRT) - "mrt.iv.obs", "mrt.iv.pred", "mrt.iv.last", - "mrt.iv.all", "mrt.ivint.all", "mrt.ivint.last" - ), - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv + name="mrt.iv.last", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv ) #' Calculate the mean residence time (MRT) for multiple-dose data with nonlinear @@ -1063,7 +833,12 @@ add.interval.col("vz.obs", desc="The terminal volume of distribution using observed Clast", formalsmap=list(cl="cl.obs"), depends=c("cl.obs", "lambda.z")) - +PKNCA.set.summary( + name="vz.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("vz.pred", FUN="pk.calc.vz", values=c(FALSE, TRUE), @@ -1072,136 +847,11 @@ add.interval.col("vz.pred", desc="The terminal volume of distribution using predicted Clast", formalsmap=list(cl="cl.pred"), depends=c("cl.pred", "lambda.z")) - -add.interval.col("vz.all", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (based on AUCall)", - desc = "Terminal volume of distribution calculated with AUCall-based CL", - formalsmap = list(cl = "cl.all"), - depends = c("cl.all", "lambda.z")) - -add.interval.col("vz.int.all", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (based on AUCint.all)", - desc = "Terminal volume of distribution using interval AUCint.all", - formalsmap = list(cl = "cl.int.all"), - depends = c("cl.int.all", "lambda.z")) - -add.interval.col("vz.int.inf.obs", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (based on AUCint.inf.obs)", - desc = "Terminal volume of distribution using interval AUCint.inf.obs", - formalsmap = list(cl = "cl.int.inf.obs"), - depends = c("cl.int.inf.obs", "lambda.z")) - -add.interval.col("vz.int.inf.pred", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (based on AUCint.inf.pred)", - desc = "Terminal volume of distribution using interval AUCint.inf.pred", - formalsmap = list(cl = "cl.int.inf.pred"), - depends = c("cl.int.inf.pred", "lambda.z")) - -add.interval.col("vz.int.last", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (based on AUCint.last)", - desc = "Terminal volume of distribution using interval AUCint.last", - formalsmap = list(cl = "cl.int.last"), - depends = c("cl.int.last", "lambda.z")) - -add.interval.col("vz.iv.all", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (for IV dosing, based on AUCall)", - desc = "Terminal volume of distribution for IV dosing using AUCall", - formalsmap = list(cl = "cl.iv.all"), - depends = c("cl.iv.all", "lambda.z")) - -add.interval.col("vz.iv.last", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (for IV dosing, based on AUClast)", - desc = "Terminal volume of distribution for IV dosing using AUClast", - formalsmap = list(cl = "cl.iv.last"), - depends = c("cl.iv.last", "lambda.z")) - -add.interval.col("vz.iv.obs", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (for IV dosing, based on AUCinf,obs)", - desc = "Terminal volume of distribution for IV dosing using observed AUCinf", - formalsmap = list(cl = "cl.iv.obs"), - depends = c("cl.iv.obs", "lambda.z")) - -add.interval.col("vz.iv.pred", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (for IV dosing, based on AUCinf,pred)", - desc = "Terminal volume of distribution for IV dosing using predicted AUCinf", - formalsmap = list(cl = "cl.iv.pred"), - depends = c("cl.iv.pred", "lambda.z")) - -add.interval.col("vz.ivint.all", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (IV dose interval, based on AUCint.all)", - desc = "Terminal volume of distribution for IV interval using AUCint.all", - formalsmap = list(cl = "cl.ivint.all"), - depends = c("cl.ivint.all", "lambda.z")) - -add.interval.col("vz.ivint.last", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (IV dose interval, based on AUCint.last)", - desc = "Terminal volume of distribution for IV interval using AUCint.last", - formalsmap = list(cl = "cl.ivint.last"), - depends = c("cl.ivint.last", "lambda.z")) - -add.interval.col("vz.last", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (based on AUClast)", - desc = "Terminal volume of distribution calculated with AUClast-based CL", - formalsmap = list(cl = "cl.last"), - depends = c("cl.last", "lambda.z")) - -add.interval.col("vz.sparse.last", - FUN = "pk.calc.vz", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vz (for sparse data, based on AUClast)", - desc = "Terminal volume of distribution from sparse sampling", - sparse = TRUE, - formalsmap = list(cl = "cl.sparse.last"), - depends = c("cl.sparse.last", "lambda.z")) - PKNCA.set.summary( - name = c( - # Volume of distribution (Vz) - "vz.obs", "vz.pred", - "vz.all", "vz.int.all", "vz.int.inf.obs", "vz.int.inf.pred", - "vz.int.last", "vz.iv.all", "vz.iv.last", "vz.iv.obs", "vz.iv.pred", - "vz.ivint.all", "vz.ivint.last", "vz.last", "vz.sparse.last" - ), - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv + name="vz.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv ) #' Calculate the steady-state volume of distribution (Vss) @@ -1223,6 +873,12 @@ add.interval.col("vss.obs", desc="The steady-state volume of distribution using observed Clast", formalsmap=list(cl="cl.obs", mrt="mrt.obs"), depends=c("cl.obs", "mrt.obs")) +PKNCA.set.summary( + name="vss.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("vss.pred", FUN="pk.calc.vss", @@ -1232,7 +888,12 @@ add.interval.col("vss.pred", desc="The steady-state volume of distribution using predicted Clast", formalsmap=list(cl="cl.pred", mrt="mrt.pred"), depends=c("cl.pred", "mrt.pred")) - +PKNCA.set.summary( + name="vss.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("vss.last", FUN="pk.calc.vss", values=c(FALSE, TRUE), @@ -1241,7 +902,12 @@ add.interval.col("vss.last", desc="The steady-state volume of distribution calculating through Tlast", formalsmap=list(cl="cl.last", mrt="mrt.last"), depends=c("cl.last", "mrt.last")) - +PKNCA.set.summary( + name="vss.last", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("vss.iv.obs", FUN="pk.calc.vss", values=c(FALSE, TRUE), @@ -1250,7 +916,12 @@ add.interval.col("vss.iv.obs", desc="The steady-state volume of distribution with intravenous infusion using observed Clast", formalsmap=list(cl="cl.obs", mrt="mrt.iv.obs"), depends=c("cl.obs", "mrt.iv.obs")) - +PKNCA.set.summary( + name="vss.iv.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("vss.iv.pred", FUN="pk.calc.vss", values=c(FALSE, TRUE), @@ -1259,7 +930,12 @@ add.interval.col("vss.iv.pred", desc="The steady-state volume of distribution with intravenous infusion using predicted Clast", formalsmap=list(cl="cl.pred", mrt="mrt.iv.pred"), depends=c("cl.pred", "mrt.iv.pred")) - +PKNCA.set.summary( + name="vss.iv.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("vss.iv.last", FUN="pk.calc.vss", values=c(FALSE, TRUE), @@ -1268,7 +944,12 @@ add.interval.col("vss.iv.last", desc="The steady-state volume of distribution with intravenous infusion calculating through Tlast", formalsmap=list(cl="cl.last", mrt="mrt.iv.last"), depends=c("cl.last", "mrt.iv.last")) - +PKNCA.set.summary( + name="vss.iv.last", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("vss.md.obs", FUN="pk.calc.vss", values=c(FALSE, TRUE), @@ -1277,7 +958,12 @@ add.interval.col("vss.md.obs", desc="The steady-state volume of distribution for nonlinear multiple-dose data using observed Clast", formalsmap=list(cl="cl.last", mrt="mrt.md.obs"), depends=c("cl.last", "mrt.md.obs")) - +PKNCA.set.summary( + name="vss.md.obs", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv +) add.interval.col("vss.md.pred", FUN="pk.calc.vss", values=c(FALSE, TRUE), @@ -1286,100 +972,11 @@ add.interval.col("vss.md.pred", desc="The steady-state volume of distribution for nonlinear multiple-dose data using predicted Clast", formalsmap=list(cl="cl.last", mrt="mrt.md.pred"), depends=c("cl.last", "mrt.md.pred")) - -add.interval.col("vss.all", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (based on AUCall)", - desc = "Steady-state volume of distribution calculated with AUCall-based CL and MRT", - formalsmap = list(cl = "cl.all", mrt = "mrt.all"), - depends = c("cl.all", "mrt.all")) - -add.interval.col("vss.int.all", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (based on AUCint.all)", - desc = "Steady-state volume of distribution using interval AUCint.all", - formalsmap = list(cl = "cl.int.all", mrt = "mrt.int.all"), - depends = c("cl.int.all", "mrt.int.all")) - -add.interval.col("vss.int.inf.obs", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (based on AUCint.inf.obs)", - desc = "Steady-state volume of distribution using interval AUCint.inf.obs", - formalsmap = list(cl = "cl.int.inf.obs", mrt = "mrt.int.inf.obs"), - depends = c("cl.int.inf.obs", "mrt.int.inf.obs")) - -add.interval.col("vss.int.inf.pred", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (based on AUCint.inf.pred)", - desc = "Steady-state volume of distribution using interval AUCint.inf.pred", - formalsmap = list(cl = "cl.int.inf.pred", mrt = "mrt.int.inf.pred"), - depends = c("cl.int.inf.pred", "mrt.int.inf.pred")) - -add.interval.col("vss.int.last", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (based on AUCint.last)", - desc = "Steady-state volume of distribution using interval AUCint.last", - formalsmap = list(cl = "cl.int.last", mrt = "mrt.int.last"), - depends = c("cl.int.last", "mrt.int.last")) - -add.interval.col("vss.iv.all", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (for IV dosing, based on AUCall)", - desc = "Steady-state volume of distribution for IV dosing using AUCall", - formalsmap = list(cl = "cl.iv.all", mrt = "mrt.iv.all"), - depends = c("cl.iv.all", "mrt.iv.all")) - -add.interval.col("vss.ivint.all", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (IV dose interval, based on AUCint.all)", - desc = "Steady-state volume of distribution for IV interval using AUCint.all", - formalsmap = list(cl = "cl.ivint.all", mrt = "mrt.ivint.all"), - depends = c("cl.ivint.all", "mrt.ivint.all")) - -add.interval.col("vss.ivint.last", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (IV dose interval, based on AUCint.last)", - desc = "Steady-state volume of distribution for IV interval using AUCint.last", - formalsmap = list(cl = "cl.ivint.last", mrt = "mrt.ivint.last"), - depends = c("cl.ivint.last", "mrt.ivint.last")) - -add.interval.col("vss.sparse.last", - FUN = "pk.calc.vss", - values = c(FALSE, TRUE), - unit_type = "volume", - pretty_name = "Vss (for sparse data, based on AUClast)", - desc = "Steady-state volume of distribution from sparse sampling", - sparse = TRUE, - formalsmap = list(cl = "cl.sparse.last", mrt = "mrt.sparse.last"), - depends = c("cl.sparse.last", "mrt.sparse.last")) - PKNCA.set.summary( - name = c( - # Volume of distribution at steady state (Vss) - "vss.obs", "vss.pred", "vss.last", "vss.iv.obs", "vss.iv.pred", "vss.iv.last", - "vss.md.obs", "vss.md.pred", "vss.all", - "vss.int.all", "vss.int.inf.obs", "vss.int.inf.pred", "vss.int.last", - "vss.iv.all", "vss.ivint.all", "vss.ivint.last", "vss.sparse.last" - ), - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv + name="vss.md.pred", + description="geometric mean and geometric coefficient of variation", + point=business.geomean, + spread=business.geocv ) #' Calculate the average concentration during an interval. diff --git a/R/pk.calc.urine.R b/R/pk.calc.urine.R index 3ac84472..964f9880 100644 --- a/R/pk.calc.urine.R +++ b/R/pk.calc.urine.R @@ -33,12 +33,29 @@ PKNCA.set.summary( #' @seealso [pk.calc.clr()], [pk.calc.fe()] #' @export pk.calc.ae <- function(conc, volume, check=TRUE) { - # Generate combined missing-data messages for conc/volume using helper - message_all <- generate_missing_messages(conc, volume, - name_a = "concentrations", - name_b = "volumes") - - ret <- sum(conc * volume) + mask_missing_conc <- is.na(conc) + mask_missing_vol <- is.na(volume) + mask_missing_both <- mask_missing_conc & mask_missing_vol + mask_missing_conc <- mask_missing_conc & !mask_missing_both + mask_missing_vol <- mask_missing_vol & !mask_missing_both + message_both <- message_conc <- message_vol <- NA_character_ + if (all(mask_missing_both)) { + message_both <- "All concentrations and volumes are missing" + } else if (any(mask_missing_both)) { + message_both <- sprintf("%g of %g concentrations and volumes are missing", sum(mask_missing_both), length(conc)) + } + if (all(mask_missing_conc)) { + message_conc <- "All concentrations are missing" + } else if (any(mask_missing_conc)) { + message_conc <- sprintf("%g of %g concentrations are missing", sum(mask_missing_conc), length(conc)) + } + if (all(mask_missing_vol)) { + message_vol <- "All volumes are missing" + } else if (any(mask_missing_vol)) { + message_vol <- sprintf("%g of %g volumes are missing", sum(mask_missing_vol), length(conc)) + } + message_all <- stats::na.omit(c(message_both, message_conc, message_vol)) + ret <- sum(conc*volume) if (length(message_all) != 0) { message <- paste(message_all, collapse = "; ") ret <- structure(ret, exclude = message) @@ -142,189 +159,3 @@ PKNCA.set.summary( point=business.geomean, spread=business.geocv ) - -#' Calculate the midpoint collection time of the last measurable excretion rate -#' -#' @param conc The concentration in the excreta (e.g., urine or feces) -#' @param volume The volume (or mass) of the sample -#' @param time The starting time of the collection interval -#' @param duration.conc The duration of the collection interval -#' @param check Should the concentration and time data be checked? -#' @return The midpoint collection time of the last measurable excretion rate, or NA/0 if not available -#' @export -pk.calc.ertlst <- function(conc, volume, time, duration.conc, check = TRUE) { - - # Generate messages about missing concentrations/volumes - message_all <- generate_missing_messages(conc, volume, - name_a = "concentrations", - name_b = "volumes") - - if (all(is.na(conc))) { - ret <- NA_real_ - } else if (all(conc %in% c(0, NA))) { - ret <- 0 - } else { - midtime <- time + duration.conc / 2 - midtime <- time + duration.conc / 2 - ret <- max(midtime[!(conc %in% c(NA, 0))]) - } - - if (length(message_all) != 0) { - message <- paste(message_all, collapse = "; ") - ret <- structure(ret, exclude = message) - } - ret -} - -# Add the column to the interval specification -add.interval.col("ertlst", - FUN="pk.calc.ertlst", - unit_type="time", - pretty_name="Tlast excretion rate", - desc="The midpoint collection time of the last measurable excretion rate (typically in urine or feces)") - -PKNCA.set.summary( - name="ertlst", - description="median and range", - point=business.median, - spread=business.range -) - -#' Calculate the maximum excretion rate -#' -#' @param conc The concentration in the excreta (e.g., urine or feces) -#' @param volume The volume (or mass) of the sample -#' @param time The starting time of the collection interval -#' @param duration.conc The duration of the collection interval -#' @param check Should the concentration data be checked? -#' @return The maximum excretion rate, or NA if not available -#' @export -pk.calc.ermax <- function(conc, volume, time, duration.conc, check = TRUE) { - - # Generate messages about missing concentrations/volumes - message_all <- generate_missing_messages(conc, volume, - name_a = "concentrations", - name_b = "volumes") - - if (length(conc) == 0 || all(is.na(conc))) { - ret <- NA - } else { - er <- conc * volume / duration.conc - ret <- max(er, na.rm=TRUE) - } - - if (length(message_all) != 0) { - message <- paste(message_all, collapse = "; ") - ret <- structure(ret, exclude = message) - } - ret -} - -add.interval.col("ermax", - FUN="pk.calc.ermax", - unit_type="amount_time", - pretty_name="Maximum excretion rate", - desc="The maximum excretion rate (typically in urine or feces)") - -PKNCA.set.summary( - name="ermax", - description="geometric mean and geometric coefficient of variation", - point=business.geomean, - spread=business.geocv -) - -#' Calculate the midpoint collection time of the maximum excretion rate -#' -#' @param conc The concentration in the excreta (e.g., urine or feces) -#' @param volume The volume (or mass) of the sample -#' @param time The starting time of the collection interval -#' @param duration.conc The duration of the collection interval -#' @param check Should the concentration and time data be checked? -#' @param first.tmax If TRUE, return the first time of maximum excretion rate; otherwise, return the last -#' @return The midpoint collection time of the maximum excretion rate, or NA if not available -#' @export -pk.calc.ertmax <- function(conc, volume, time, duration.conc, check = TRUE, first.tmax = NULL) { - - # Generate messages about missing concentrations/volumes - message_all <- generate_missing_messages(conc, volume, - name_a = "concentrations", - name_b = "volumes") - - if (length(conc) == 0 || all(conc %in% c(NA, 0))) { - ret <- NA - } else { - er <- conc * volume / duration.conc - ermax <- pk.calc.ermax(conc, volume, time, duration.conc, check = FALSE) - midtime <- time + duration.conc / 2 - ret <- midtime[er %in% ermax] - - if (first.tmax) { - ret <- ret[1] - } else { - ret <- ret[length(ret)] - } - } - - if (length(message_all) != 0) { - message <- paste(message_all, collapse = "; ") - ret <- structure(ret, exclude = message) - } - ret -} - -add.interval.col("ertmax", - FUN="pk.calc.ertmax", - unit_type="time", - pretty_name="Tmax excretion rate", - desc="The midpoint collection time of the maximum excretion rate (typically in urine or feces)") - -PKNCA.set.summary( - name="ertmax", - description="median and range", - point=business.median, - spread=business.range -) - - - -# Helper to generate missing-data checking messages for paired vectors -# -# This function accepts two columns/vectors (for example, concentrations -# and volumes). It computes missingness internally and produces a character -# vector of human-readable messages describing the missingness that matches -# the style used in the package (used previously in `pk.calc.ae`). -generate_missing_messages <- function(a, b, - name_a = deparse(substitute(a)), - name_b = deparse(substitute(b))) { - - mask_a <- is.na(a) - mask_b <- is.na(b) - - mask_both <- mask_a & mask_b - mask_a_only <- mask_a & !mask_both - mask_b_only <- mask_b & !mask_both - - msg_both <- msg_a <- msg_b <- NA_character_ - n <- length(mask_a) - - if (all(mask_both)) { - msg_both <- sprintf("All %s and %s are missing", name_a, name_b) - } else if (any(mask_both)) { - msg_both <- sprintf("%g of %g %s and %s are missing", sum(mask_both), n, name_a, name_b) - } - - if (all(mask_a_only)) { - msg_a <- sprintf("All %s are missing", name_a) - } else if (any(mask_a_only)) { - msg_a <- sprintf("%g of %g %s are missing", sum(mask_a_only), n, name_a) - } - - if (all(mask_b_only)) { - msg_b <- sprintf("All %s are missing", name_b) - } else if (any(mask_b_only)) { - msg_b <- sprintf("%g of %g %s are missing", sum(mask_b_only), n, name_b) - } - - # Return non-NA messages - stats::na.omit(c(msg_both, msg_a, msg_b)) -} diff --git a/R/sparse.R b/R/sparse.R index cff1710b..7a59f2cc 100644 --- a/R/sparse.R +++ b/R/sparse.R @@ -401,184 +401,3 @@ PKNCA.set.summary( is_sparse_pk <- function(object) { UseMethod("is_sparse_pk") } - - - -#' Calculate the variance for the AUMC of sparsely sampled PK -#' -#' This function calculates the variance of the area under the first moment -#' curve (AUMC) for sparse PK data. It follows the same methodology as -#' [var_sparse_auc()] but applies to the moment curve (time × concentration). -#' -#' Equation 7.vii in Nedelman and Jia, 1998 is adapted for AUMC: -#' -#' \deqn{var\left(\hat{AUMC}\right) = \sum\limits_{i=0}^m\left(\frac{w_i^2 s_i^2}{r_i}\right) + 2\sum\limits_{i 0) { - rlang::warn( - message = "Cannot yet calculate sparse degrees of freedom for multiple samples per subject", - class = "pknca_sparse_df_multi" - ) - df <- NA_real_ - } - - attr(var_aumc, "df") <- df - var_aumc -} - -#' Calculate AUMC and related parameters using sparse NCA methods -#' -#' This is the exact analog of [pk.calc.sparse_auc()] but for the first moment curve. -#' -#' @inheritParams pk.calc.sparse_auc -#' @returns A data.frame with columns: -#' \item{sparse_aumc}{The estimated AUMC} -#' \item{sparse_aumc_se}{Standard error of the AUMC estimate} -#' \item{sparse_aumc_df}{Degrees of freedom for the variance estimate} -#' @family Sparse Methods -#' @export -pk.calc.sparse_aumc <- function(conc, time, subject, - method = NULL, - auc.type = "AUClast", - ..., - options = list()) { - sparse_pk <- as_sparse_pk(conc = conc, time = time, subject = subject) - sparse_pk_wt <- sparse_auc_weight_linear(sparse_pk) - sparse_pk_mean <- sparse_mean(sparse_pk = sparse_pk_wt, - sparse_mean_method = "arithmetic mean, <=50% BLQ") - - aumc <- - pk.calc.aumc( - conc = sparse_pk_attribute(sparse_pk_mean, "mean"), - time = sparse_pk_attribute(sparse_pk_mean, "time"), - auc.type = auc.type, - method = "linear" - ) - - var_aumc <- var_sparse_aumc(sparse_pk_mean) - - data.frame( - sparse_aumc = aumc, - sparse_aumc_se = sqrt(as.numeric(var_aumc)), - sparse_aumc_df = attr(var_aumc, "df") - ) -} - -#' @describeIn pk.calc.sparse_aumc Compute the AUMClast for sparse PK -#' @export -pk.calc.sparse_aumclast <- function(conc, time, subject, ..., options = list()) { - if ("auc.type" %in% names(list(...))) { - rlang::abort( - message = "auc.type cannot be changed when calling pk.calc.sparse_aumclast, please use pk.calc.sparse_aumc", - class = "pknca_sparse_aumclast_change_auc_type" - ) - } - ret <- pk.calc.sparse_aumc( - conc = conc, time = time, subject = subject, - ..., options = options, - auc.type = "AUClast", - lambda.z = NA - ) - names(ret)[names(ret) == "sparse_aumc"] <- "sparse_aumclast" - ret -} - -# Column registrations -add.interval.col( - "sparse_aumclast", - sparse = TRUE, - FUN = "pk.calc.sparse_aumclast", - values = c(FALSE, TRUE), - unit_type = "aumc", - pretty_name = "Sparse AUMClast", - desc = "For sparse PK sampling, the area under the moment curve from the beginning of the interval to the last concentration above the limit of quantification" -) -PKNCA.set.summary( - name = "sparse_aumclast", - description = "geometric mean and geometric coefficient of variation", - point = business.geomean, - spread = business.geocv -) - -add.interval.col( - "sparse_aumc_se", - FUN = NA, - values = c(FALSE, TRUE), - unit_type = "aumc", - pretty_name = "Sparse AUMC standard error", - desc = "For sparse PK sampling, the standard error of the area under the moment curve", - depends = "sparse_aumclast" -) -PKNCA.set.summary( - name = "sparse_aumc_se", - description = "arithmetic mean and standard deviation", - point = business.mean, - spread = business.sd -) - -add.interval.col( - "sparse_aumc_df", - FUN = NA, - values = c(FALSE, TRUE), - unit_type = "count", - pretty_name = "Sparse AUMC degrees of freedom", - desc = "For sparse PK sampling, the degrees of freedom for the AUMC variance estimate", - depends = "sparse_aumclast" -) -PKNCA.set.summary( - name = "sparse_aumc_df", - description = "arithmetic mean and standard deviation", - point = business.mean, - spread = business.sd -) diff --git a/R/unit-support.R b/R/unit-support.R index 74982d4a..46cba380 100644 --- a/R/unit-support.R +++ b/R/unit-support.R @@ -77,7 +77,6 @@ pknca_units_table <- function(concu, doseu, amountu, timeu, pknca_units_table_dose(doseu = doseu), pknca_units_table_conc_dose(concu=concu, doseu=doseu), pknca_units_table_conc_time(concu=concu, timeu=timeu), - pknca_units_table_time_amount(timeu=timeu, amountu=amountu), pknca_units_table_conc_time_dose(concu=concu, timeu=timeu, doseu=doseu), pknca_units_table_conc_time_amount(concu=concu, timeu=timeu, amountu=amountu), pknca_units_table_conc_time_amount_dose(concu=concu, timeu=timeu, amountu=amountu, doseu=doseu) @@ -368,19 +367,6 @@ pknca_units_table_conc_time_amount <- function(concu, timeu, amountu) { ) } -pknca_units_table_time_amount <- function(timeu, amountu) { - if (useless(timeu) || useless(amountu)) { - time_amount <- NA_character_ - } else { - time_amount <- sprintf("%s*%s", timeu, amountu) - } - data.frame( - PPORRESU = time_amount, - PPTESTCD = pknca_find_units_param(unit_type = "amount_time"), - stringsAsFactors = FALSE - ) -} - pknca_units_table_conc_time_amount_dose <- function(concu, timeu, amountu, doseu) { if (useless(concu) || useless(timeu) || useless(amountu) || useless(doseu)) { renal_clearance_dosenorm <- NA_character_ diff --git a/tests/testthat/test-pk.calc.urine.R b/tests/testthat/test-pk.calc.urine.R index 392fae19..3c066005 100644 --- a/tests/testthat/test-pk.calc.urine.R +++ b/tests/testthat/test-pk.calc.urine.R @@ -60,75 +60,3 @@ test_that("pk.calc.fe", { 0.3, info="fe is calculated correctly with both vector/scalar") }) - -test_that("pk.calc.ertlst", { - # All NA - expect_equal( - pk.calc.ertlst(conc = c(NA, NA), volume = c(1, 1), time = c(0, 1), duration.conc = c(1, 1)), - structure(NA_real_, exclude = "All concentrations are missing") - ) - expect_equal( - pk.calc.ertlst(conc = c(NA, NA), volume = c(NA, NA), time = c(0, 1), duration.conc = c(1, 1)), - structure(NA_real_, exclude = "All concentrations and volumes are missing") - ) - # All 0 or NA - expect_equal( - pk.calc.ertlst(conc = c(0, NA), volume = c(1, 1), time = c(0, 1), duration.conc = c(1, 1)), - structure(0, exclude = "1 of 2 concentrations are missing") - ) - # Normal case - expect_equal( - pk.calc.ertlst(conc = c(1, 2, 0), volume = c(1, 1, 1), time = c(0, 1, 2), duration.conc = c(1, 1, 1)), - max(c(0, 1) + 1/2) - ) -}) - -test_that("pk.calc.ermax", { - # All NA - expect_equal( - pk.calc.ermax(conc = c(NA, NA), volume = c(1, 1), time = c(0, 1), duration.conc = c(1, 1)), - structure(NA, exclude = "All concentrations are missing") - ) - # Normal case - expect_equal( - pk.calc.ermax(conc = c(1, 2, 3), volume = c(2, 2, 2), time = c(0, 1, 2), duration.conc = c(2, 2, 2)), - max(c(1, 2, 3) * 2 / 2) - ) -}) - -test_that("pk.calc.ertmax", { - # All NA or 0 - expect_equal( - pk.calc.ertmax(conc = c(NA, 0), volume = c(1, 1), time = c(0, 1), duration.conc = c(1, 1)), - structure(NA, exclude = "1 of 2 concentrations are missing") - ) - # Normal case, last tmax - expect_equal( - pk.calc.ertmax(conc = c(1, 3, 2), volume = c(2, 2, 2), time = c(0, 1, 2), duration.conc = c(2, 2, 2), first.tmax = FALSE), - (1 + 2/2) - ) - # Normal case, first tmax - expect_equal( - pk.calc.ertmax(conc = c(1, 3, 2), volume = c(2, 2, 2), time = c(0, 1, 2), duration.conc = c(2, 2, 2), first.tmax = TRUE), - (1 + 2/2) - ) - # Multiple maxima - expect_equal( - pk.calc.ertmax(conc = c(1, 3, 3), volume = c(2, 2, 2), time = c(0, 1, 2), duration.conc = c(2, 2, 2), first.tmax = TRUE), - (1 + 2/2) - ) - expect_equal( - pk.calc.ertmax(conc = c(1, 3, 3), volume = c(2, 2, 2), time = c(0, 1, 2), duration.conc = c(2, 2, 2), first.tmax = FALSE), - (2 + 2/2) - ) -}) - -test_that("generate_missing_messages", { - # Ensure that the deparse(substitute()) methods work - conc <- NA_real_ - volume <- NA_real_ - expect_equal( - as.character(generate_missing_messages(conc, volume)), - "All conc and volume are missing" - ) -})