From 3b2408ca7a836e458ea6a9795d2cd243e485d8e1 Mon Sep 17 00:00:00 2001 From: Gero1999 Date: Thu, 28 Aug 2025 07:03:50 +0200 Subject: [PATCH 1/7] checktime without excluded points --- R/class-PKNCAconc.R | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/R/class-PKNCAconc.R b/R/class-PKNCAconc.R index f3bd9bd8..71f26820 100644 --- a/R/class-PKNCAconc.R +++ b/R/class-PKNCAconc.R @@ -100,14 +100,7 @@ PKNCAconc.data.frame <- function(data, formula, subject, if (length(parsed_form$time) != 1) { stop("The right hand side of the formula (excluding groups) must have exactly one variable") } - # Do some general checking of the concentration and time data to give an early - # error if the data are not correct. Do not check monotonic.time because the - # data may contain information for more than one subject. - assert_conc_time( - conc = data[[parsed_form$concentration]], - time = data[[parsed_form$time]], - sorted_time = FALSE - ) + # Assign the subject if (missing(subject)) { subject <- parsed_form$groups$group_vars[length(parsed_form$groups$group_vars)] @@ -139,6 +132,17 @@ PKNCAconc.data.frame <- function(data, formula, subject, } class(ret) <- c("PKNCAconc", class(ret)) ret <- setExcludeColumn(ret, exclude = exclude, dataname = getDataName.PKNCAconc(ret)) + + # Do some general checking of the concentration and time data. + # Do not check monotonic.time because the data may contain information + # for more than one subject. Disconsider points that will be excluded. + is_excluded <- !is.na(data[[exclude]]) + assert_conc_time( + conc = data[[parsed_form$concentration]][!is_excluded], + time = data[[parsed_form$time]][!is_excluded], + sorted_time = FALSE + ) + # Values must be unique (one value per measurement), check after the exclusion # column has been added to the object so that exclusions can be accounted for # in duplicate checking. From 27bb57989a13596517bb85afe030a2fe0cf1a2e4 Mon Sep 17 00:00:00 2001 From: Gero1999 Date: Thu, 28 Aug 2025 07:04:30 +0200 Subject: [PATCH 2/7] test: add PKNCAconc case with exclusion on NA timepoint --- tests/testthat/test-class-PKNCAconc.R | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/testthat/test-class-PKNCAconc.R b/tests/testthat/test-class-PKNCAconc.R index 4087a5da..78976a25 100644 --- a/tests/testthat/test-class-PKNCAconc.R +++ b/tests/testthat/test-class-PKNCAconc.R @@ -12,6 +12,12 @@ test_that("PKNCAconc expected errors", { ) }) +test_that("PKNCAconc not expected errors", { + # EMissing time points that are excluded are not checked + tmp.conc <- data.frame(time = c(1, NA), conc = c(1, NA), exclude = c(NA, "foo")) + expect_no_error(PKNCAconc(conc~time, data = tmp.conc, exclude = "exclude")) +}) + test_that("PKNCAconc", { tmp.conc <- generate.conc(nsub=5, ntreat=2, time.points=0:24) tmp.conc.analyte <- generate.conc(nsub=5, ntreat=2, time.points=0:24, From ade308ba7fbe1c8181c32d1d3b40637320e9ae92 Mon Sep 17 00:00:00 2001 From: Gero1999 Date: Thu, 28 Aug 2025 07:08:18 +0200 Subject: [PATCH 3/7] news: add fix as a minor change --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 67f40491..9c02daba 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,7 @@ the dosing including dose amount and route. * Units for fraction excretion parameter (fe) are now accurately captured as amount/dose units rather than "fraction" (#426) +* The `PKNCAconc` won't give an error for a concentration-time check when the issue is due to an excluded point # PKNCA 0.12.0 From b93a8e67ce0c90df205b5c56df07e03cacf234a0 Mon Sep 17 00:00:00 2001 From: Gero1999 Date: Thu, 28 Aug 2025 19:25:47 +0200 Subject: [PATCH 4/7] PKNCA.Rd update --- man/PKNCA.Rd | 1 + 1 file changed, 1 insertion(+) diff --git a/man/PKNCA.Rd b/man/PKNCA.Rd index 1aa1f6de..19a5fe7a 100644 --- a/man/PKNCA.Rd +++ b/man/PKNCA.Rd @@ -52,6 +52,7 @@ Useful links: Authors: \itemize{ \item Clare Buckeridge \email{clare.buckeridge@pfizer.com} + \item Gerardo Jose Rodriguez \email{gerardo.jrac@gmail.com} (\href{https://orcid.org/0000-0003-1413-0060}{ORCID}) } Other contributors: From 45c52a4b9292d8d3383fe209e13f4ef4459847e4 Mon Sep 17 00:00:00 2001 From: Gero1999 Date: Thu, 28 Aug 2025 20:11:43 +0200 Subject: [PATCH 5/7] fix: test with NULL exclude --- R/class-PKNCAconc.R | 7 ++++++- tests/testthat/test-class-PKNCAconc.R | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/R/class-PKNCAconc.R b/R/class-PKNCAconc.R index 71f26820..8698e0ab 100644 --- a/R/class-PKNCAconc.R +++ b/R/class-PKNCAconc.R @@ -136,7 +136,12 @@ PKNCAconc.data.frame <- function(data, formula, subject, # Do some general checking of the concentration and time data. # Do not check monotonic.time because the data may contain information # for more than one subject. Disconsider points that will be excluded. - is_excluded <- !is.na(data[[exclude]]) + if (!is.null(exclude)) { + is_excluded <- !is.na(data[[exclude]]) + } else { + is_excluded <- rep(FALSE, nrow(data)) + } + assert_conc_time( conc = data[[parsed_form$concentration]][!is_excluded], time = data[[parsed_form$time]][!is_excluded], diff --git a/tests/testthat/test-class-PKNCAconc.R b/tests/testthat/test-class-PKNCAconc.R index 78976a25..7c09f3cc 100644 --- a/tests/testthat/test-class-PKNCAconc.R +++ b/tests/testthat/test-class-PKNCAconc.R @@ -13,9 +13,13 @@ test_that("PKNCAconc expected errors", { }) test_that("PKNCAconc not expected errors", { - # EMissing time points that are excluded are not checked + # Missing time points that are excluded are not checked tmp.conc <- data.frame(time = c(1, NA), conc = c(1, NA), exclude = c(NA, "foo")) expect_no_error(PKNCAconc(conc~time, data = tmp.conc, exclude = "exclude")) + + # Exclude column can be not defined (NULL) + tmp.conc <- data.frame(time = c(1, 2), conc = c(1, 2)) + expect_no_error(PKNCAconc(conc~time, data = tmp.conc, exclude = NULL)) }) test_that("PKNCAconc", { From 75c49a86782abf241aa7a47d7fd16cb4cced0fa3 Mon Sep 17 00:00:00 2001 From: Gero1999 Date: Fri, 12 Sep 2025 22:41:37 +0200 Subject: [PATCH 6/7] test: clarify error case msg --- tests/testthat/test-class-PKNCAconc.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-class-PKNCAconc.R b/tests/testthat/test-class-PKNCAconc.R index 7c09f3cc..56bef9ea 100644 --- a/tests/testthat/test-class-PKNCAconc.R +++ b/tests/testthat/test-class-PKNCAconc.R @@ -12,7 +12,7 @@ test_that("PKNCAconc expected errors", { ) }) -test_that("PKNCAconc not expected errors", { +test_that("PKNCAconc does not error for excluded, invalid times (#310)", { # Missing time points that are excluded are not checked tmp.conc <- data.frame(time = c(1, NA), conc = c(1, NA), exclude = c(NA, "foo")) expect_no_error(PKNCAconc(conc~time, data = tmp.conc, exclude = "exclude")) From aa328557543e73dd8307e659c532606fe7d2ef9b Mon Sep 17 00:00:00 2001 From: Gero1999 Date: Fri, 12 Sep 2025 22:56:21 +0200 Subject: [PATCH 7/7] fix: PKNCAdose ignores missing times excluded --- NEWS.md | 5 +++-- R/class-PKNCAdose.R | 16 ++++++++++++---- tests/testthat/test-class-PKNCAdose.R | 10 ++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index 318b6471..e2adb5cc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,9 @@ the dosing including dose amount and route. * `get_halflife_points()` now correctly accounts for start time != 0 and sets times outside of any interval to `NA` (#470) +* The `PKNCAconc` function won't give an error for a concentration-time check +when the issue is due to an excluded point (#310) +* The `PKNCAdose` function won't give an error for a missing-time check when the issue is due to an excluded point (#310) ## New features @@ -27,8 +30,6 @@ the dosing including dose amount and route. * `lambda.z` calculations will now only consider time points that occur after the end of the latest dose administration (#139) * `aucint.inf.pred` is `NA` when half-life is not estimable (#450) -* The `PKNCAconc` function won't give an error for a concentration-time check -when the issue is due to an excluded point (#310) ## New features diff --git a/R/class-PKNCAdose.R b/R/class-PKNCAdose.R index 18e6fe56..d8ae52d4 100644 --- a/R/class-PKNCAdose.R +++ b/R/class-PKNCAdose.R @@ -125,7 +125,15 @@ PKNCAdose.data.frame <- function(data, formula, route, rate, duration, # in duplicate checking. duplicate_check(object = ret, data_type = "dosing") - mask.indep <- is.na(getIndepVar.PKNCAdose(ret)) + # Do some general checking of the dose and time data. + # Disconsider points that will be excluded. + if (!is.null(exclude)) { + is_excluded <- !is.na(data[[exclude]]) + } else { + is_excluded <- rep(FALSE, nrow(data)) + } + # Check for missing independent variable (time) in non-excluded rows + mask.indep <- is.na(getIndepVar.PKNCAdose(ret)) & !is_excluded if (any(mask.indep) & !all(mask.indep)) { stop("Some but not all values are missing for the independent variable, please see the help for PKNCAdose for how to specify the formula and confirm that your data has dose times for all doses.") } @@ -207,17 +215,17 @@ setDuration.PKNCAdose <- function(object, duration, rate, dose, ...) { if (missing(dose)) { dose <- object$columns$dose } - if (missing(duration) & missing(rate)) { + if (missing(duration) && missing(rate)) { object <- setAttributeColumn(object=object, attr_name="duration", default_value=0, message_if_default="Assuming instant dosing (duration=0)") - } else if (!missing(duration) & !missing(rate)) { + } else if (!missing(duration) && !missing(rate)) { stop("Both duration and rate cannot be given at the same time") # TODO: A consistency check could be done, but that would get into # requiring near-equal checks for floating point error. } else if (!missing(duration)) { object <- setAttributeColumn(object=object, attr_name="duration", col_or_value=duration) - } else if (!missing(rate) & !missing(dose) && !is.na(dose)) { + } else if (!missing(rate) && !missing(dose) && !is.na(dose)) { tmprate <- getColumnValueOrNot(object$data, rate, "rate") tmpdose <- getColumnValueOrNot(object$data, dose, "dose") duration <- tmpdose$data[[tmpdose$name]]/tmprate$data[[tmprate$name]] diff --git a/tests/testthat/test-class-PKNCAdose.R b/tests/testthat/test-class-PKNCAdose.R index 13787a87..100387f5 100644 --- a/tests/testthat/test-class-PKNCAdose.R +++ b/tests/testthat/test-class-PKNCAdose.R @@ -579,3 +579,13 @@ test_that("PKNCAdose units (#336)", { structure("doseu_x", unit_type = "column") ) }) + +test_that("PKNCAdose does not error for excluded, invalid times (#310)", { + # Missing time points that are excluded are not checked + tmp.dose <- data.frame(time = c(1, NA), dose = c(1, NA), exclude = c(NA, "foo")) + expect_no_error(PKNCAdose(tmp.dose, formula = dose~time, exclude = "exclude")) + + # Exclude column can be not defined (NULL) + tmp.dose <- data.frame(time = c(1, 2), dose = c(1, 2)) + expect_no_error(PKNCAdose(tmp.dose, formula = dose~time, exclude = NULL)) +})