From f2533b711fcfb3869dcac9f5503698085fd90dc3 Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Tue, 10 Jun 2025 11:39:25 -0400 Subject: [PATCH] Initial steps to help with choosing parameters for intervals --- NEWS.md | 6 +++ R/assertions.R | 17 +++++++++ R/interval_model.R | 56 ++++++++++++++++++++++++++++ man/assert_choose_params_control.Rd | 38 +++++++++++++++++++ man/choose_params.Rd | 23 ++++++++++++ tests/testthat/test-assertions.R | 15 +++++++- tests/testthat/test-interval_model.R | 47 +++++++++++++++++++++++ 7 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 R/interval_model.R create mode 100644 man/assert_choose_params_control.Rd create mode 100644 man/choose_params.Rd create mode 100644 tests/testthat/test-interval_model.R diff --git a/NEWS.md b/NEWS.md index 67f40491..2fd7158f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,12 @@ the dosing including dose amount and route. # PKNCA (development version) +## New features + +* `choose_params()` is a new function that helps choose the parameters to use + based on parameters you want to calculate based on dosing route, number of + doses, and other choices. + ## Minor changes (unlikely to affect PKNCA use) * Units for fraction excretion parameter (fe) are now accurately captured as diff --git a/R/assertions.R b/R/assertions.R index 07d88150..87eacf73 100644 --- a/R/assertions.R +++ b/R/assertions.R @@ -196,6 +196,23 @@ assert_aucmethod <- function(method = c("lin up/log down", "linear", "lin-log")) match.arg(method) } +#' Assert that a character vector only contains PKNCA parameter names +#' @param param A vector of parameter names to check +assert_param_name <- function(param) { + missing_param <- setdiff(param, names(get.interval.cols())) + if (length(missing_param) > 0) { + stop( + paste(missing_param, collapse = ", "), + ngettext( + length(missing_param), + msg1 = " is not a valid PKNCA parameter name", + msg2 = " are not valid PKNCA parameter names" + ) + ) + } + param +} + #' Assert that an object is a PKNCAdata object #' @param object The PKNCAdata object #' @returns The PKNCAdata object (confirmed to be usable) diff --git a/R/interval_model.R b/R/interval_model.R new file mode 100644 index 00000000..f353873c --- /dev/null +++ b/R/interval_model.R @@ -0,0 +1,56 @@ +#' Choose parameters for an interval +#' +#' @inheritParams assert_choose_params_control +#' @inheritParams assert_choose_params_auc_choices +#' @inheritParams assert_choose_params_iv_choices +choose_params <- function(route, num_doses, sample_type, clast_type, auc_choices, iv_choices) { + control <- assert_choose_params_control(route, num_doses, sample_type, clast_type) + auc_choices <- assert_choose_params_auc_choices(auc_choices, route = control$route, clast_type = control$clast_type) + iv_choices <- assert_choose_params_iv_choices(iv_choices, route = control$route) +} + +#' Verify parameter options for choose_params +#' +#' @param route The route of administration +#' @param num_doses Were "single" or "multiple" doses administered +#' @param sample_type Was this a "spot" sample (typical for serum, plasma, and +#' blood) or an "interval" sample (typical for urine and feces) +#' @param clast_type Should "pred"icted or "obs"erved clast be used? +#' @returns A list of valid parameters +assert_choose_params_control <- function(route, num_doses, sample_type, clast_type) { + checkmate::assert_choice(route, choices = c("extravascular", "intravascular"), null.ok = FALSE) + checkmate::assert_choice(num_doses, choices = c("single", "multiple"), null.ok = FALSE) + checkmate::assert_choice(sample_type, choices = c("spot", "interval"), null.ok = FALSE) + checkmate::assert_choice(clast_type, choices = c("pred", "obs"), null.ok = FALSE) +} + +#' @describeIn assert_choose_params_control Choose valid AUC types +#' +#' @param auc_choices Zero or more types of AUC to calculate ("all", "inf", "last") +#' @param auc_prefix "auc" or "aumc" to indicate what type of AUC calculation it will be +#' @returns A character vector of AUC types to calculate +assert_choose_params_auc_choices <- function(auc_choices, route, clast_type, auc_prefix) { + if (is.null(auc_choices)) { + return(character()) + } + auc_choices <- unique(checkmate::assert_subset(auc_choices, choices = c("all", "inf", "last"))) + which_inf <- which(auc_choices %in% "inf") + if (length(which_inf) > 0) { + auc_choices[which_inf] <- paste(auc_choices[which_inf], clast_type, sep = ".") + } + auc_prefix <- checkmate::assert_choice(auc_prefix, choices = c("auc", "aumc")) + if (route %in% "intravascular") { + ret <- paste0(auc_prefix, "iv") + } else { + ret <- auc_prefix + } + ret <- paste0(ret, auc_choices) + assert_param_name(ret) +} + +#' Choose IV-specific parameters +#' +#' @param iv_choices intravenous-specific parameter names ("c0", "ceoi") +assert_choose_params_iv_choices <- function(iv_choices) { + unique(checkmate::assert_subset(x = iv_choices, choices = c("c0", "ceoi")) +} diff --git a/man/assert_choose_params_control.Rd b/man/assert_choose_params_control.Rd new file mode 100644 index 00000000..42282d01 --- /dev/null +++ b/man/assert_choose_params_control.Rd @@ -0,0 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interval_model.R +\name{assert_choose_params_control} +\alias{assert_choose_params_control} +\alias{assert_choose_params_auc_types} +\title{Verify parameter options for choose_params} +\usage{ +assert_choose_params_control(route, num_doses, sample_type, clast_type) + +assert_choose_params_auc_types(auc_types, route, clast_type, auc_prefix) +} +\arguments{ +\item{route}{The route of administration} + +\item{num_doses}{Were "single" or "multiple" doses administered} + +\item{sample_type}{Was this a "spot" sample (typical for serum, plasma, and +blood) or an "interval" sample (typical for urine and feces)} + +\item{clast_type}{Should "pred"icted or "obs"erved clast be used?} + +\item{auc_types}{Zero or more types of AUC to calculate ("all", "inf", "last")} + +\item{auc_prefix}{"auc" or "aumc" to indicate what type of AUC calculation it will be} +} +\value{ +A list of valid parameters + +A character vector of AUC types to calculate +} +\description{ +Verify parameter options for choose_params +} +\section{Functions}{ +\itemize{ +\item \code{assert_choose_params_auc_types()}: Choose valid AUC types + +}} diff --git a/man/choose_params.Rd b/man/choose_params.Rd new file mode 100644 index 00000000..54e4e596 --- /dev/null +++ b/man/choose_params.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interval_model.R +\name{choose_params} +\alias{choose_params} +\title{Choose parameters for an interval} +\usage{ +choose_params(route, num_doses, sample_type, clast_type, auc_types) +} +\arguments{ +\item{route}{The route of administration} + +\item{num_doses}{Were "single" or "multiple" doses administered} + +\item{sample_type}{Was this a "spot" sample (typical for serum, plasma, and +blood) or an "interval" sample (typical for urine and feces)} + +\item{clast_type}{Should "pred"icted or "obs"erved clast be used?} + +\item{auc_types}{Zero or more types of AUC to calculate ("all", "inf", "last")} +} +\description{ +Choose parameters for an interval +} diff --git a/tests/testthat/test-assertions.R b/tests/testthat/test-assertions.R index 169f3cf3..ad56f28e 100644 --- a/tests/testthat/test-assertions.R +++ b/tests/testthat/test-assertions.R @@ -99,6 +99,17 @@ test_that("assert_lambdaz", { ) }) +test_that("assert_param_name", { + expect_error( + assert_param_name("foo"), + regexp = "foo is not a valid PKNCA parameter name" + ) + expect_error( + assert_param_name(c("foo", "bar")), + regexp = "foo, bar are not valid PKNCA parameter names" + ) +}) + test_that("assert_PKNCAdata", { expect_error( assert_PKNCAdata("A"), @@ -113,12 +124,12 @@ test_that("element_find", { element_find(values5), element_find(values10) ) - + expect_equal( element_find(values5), "Elements 1, 2, 3, 4, 5" ) - + expect_equal( element_find(values10), "Elements 1, 2, 3, 4, 5" diff --git a/tests/testthat/test-interval_model.R b/tests/testthat/test-interval_model.R new file mode 100644 index 00000000..fa2e7dbf --- /dev/null +++ b/tests/testthat/test-interval_model.R @@ -0,0 +1,47 @@ +test_that("assert_choose_params_auc_choices", { + # no parameters are required + expect_equal( + assert_choose_params_auc_choices(auc_choices = NULL), + character() + ) + # multiple parmaeters may be returned + expect_equal( + assert_choose_params_auc_choices(auc_choices = c("last", "all", "inf"), route = "intravascular", clast_type = "pred", auc_prefix = "auc"), + c("aucivlast", "aucivall", "aucivinf.pred") + ) + # Verify that all valid choices return valid parameter names + for (current_auc_choices in c("all", "inf", "last")) { + for (current_route in c("extravascular", "intravascular")) { + for (current_clast_type in c("pred", "obs")) { + for (current_auc_prefix in c("auc", "aumc")) { + # TODO: multiple AUMC IV parameters do not exist + if (current_auc_prefix == "aumc" && current_route == "intravascular") { + expect_error( + assert_choose_params_auc_choices( + auc_choices = current_auc_choices, + route = current_route, + clast_type = current_clast_type, + auc_prefix = current_auc_prefix + ), + regexp = "not .*valid PKNCA parameter name" + ) + } else { + expect_error( + assert_choose_params_auc_choices( + auc_choices = current_auc_choices, + route = current_route, + clast_type = current_clast_type, + auc_prefix = current_auc_prefix + ), + NA + ) + } + } + } + } + } + expect_equal( + assert_choose_params_auc_choices(auc_choices = "inf", route = "extravascular", clast_type = "pred", auc_prefix = "auc"), + "aucinf.pred" + ) +})