From 30a2b05c9b89bbc02f2e6eff3f60e2a59aee73c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerardo=20J=2E=20Rodr=C3=ADguez?= <68994823+Gero1999@users.noreply.github.com> Date: Tue, 30 Jun 2026 10:18:50 +0200 Subject: [PATCH 1/5] Modify assert_conc_time to allow missing concentrations Allow missing concentrations in assert_conc_time and filter out NA values from conc, time, and subject. --- R/sparse.R | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/R/sparse.R b/R/sparse.R index 461396d2..ffd0297c 100644 --- a/R/sparse.R +++ b/R/sparse.R @@ -14,8 +14,15 @@ as_sparse_pk <- function(conc, time, subject) { subject <- conc$subject conc <- conc$conc } - assert_conc_time(conc = conc, time = time, any_missing_conc = FALSE, sorted_time = FALSE) + assert_conc_time(conc = conc, time = time, any_missing_conc = TRUE, sorted_time = FALSE) checkmate::check_vector(subject, any.missing=FALSE, len=length(conc), null.ok=FALSE) + # Drop observations with missing concentrations so that per-timepoint means, + # variances, and subject counts reflect only available data. + mask_ok <- !is.na(conc) + conc <- conc[mask_ok] + time <- time[mask_ok] + subject <- subject[mask_ok] + unique_times <- sort(unique(time)) ret <- list() for (current_time in unique_times) { @@ -626,4 +633,4 @@ PKNCA.set.summary( description = "arithmetic mean and standard deviation", point = business.mean, spread = business.sd -) \ No newline at end of file +) From 46a1a778d98ea5795f54f345ec8d33a3779a4fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerardo=20J=2E=20Rodr=C3=ADguez?= <68994823+Gero1999@users.noreply.github.com> Date: Tue, 30 Jun 2026 10:19:33 +0200 Subject: [PATCH 2/5] Add tests for NA handling in sparse functions --- tests/testthat/test-sparse.R | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/testthat/test-sparse.R b/tests/testthat/test-sparse.R index e685d09e..98f7cf9d 100644 --- a/tests/testthat/test-sparse.R +++ b/tests/testthat/test-sparse.R @@ -33,6 +33,30 @@ test_that("sparse_auc", { expect_equal(sparse_serial$sparse_auc_df, structure(auclast_df_serial, method=c("AUC: linear", "Sparse: arithmetic mean, <=50% BLQ"))) }) +test_that("as_sparse_pk drops NA concentrations (#563)", { + sparse_pk <- as_sparse_pk( + conc = c(0, 0, 5, 7, 3, NA), + time = c(0, 0, 4, 4, 24, 24), + subject = c(1, 2, 3, 4, 5, 6) + ) + # The NA row (subject 6, time 24) should be dropped + expect_length(sparse_pk, 3) # 3 unique times: 0, 4, 24 + expect_equal(sparse_pk[[3]]$conc, 3) + expect_equal(sparse_pk[[3]]$subject, 5) +}) + +test_that("sparse_auc tolerates NA concentrations (#563)", { + result <- pk.calc.sparse_auc( + conc = c(0, 0, 5, 7, 3, NA), + time = c(0, 0, 4, 4, 24, 24), + subject = 1:6 + ) + expect_false(is.na(result$sparse_auc)) + # Mean profile: time 0 = 0, time 4 = 6, time 24 = 3 + # AUC linear: 0.5*(0+6)*4 + 0.5*(6+3)*20 = 12 + 90 = 102 + expect_equal(as.numeric(result$sparse_auc), 102) +}) + test_that("sparse_auclast expected errors", { expect_error( pk.calc.sparse_auclast(auc.type = "foo"), From 591d22bb918ffcbabb732a14da16b83d73b8fc2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerardo=20J=2E=20Rodr=C3=ADguez?= <68994823+Gero1999@users.noreply.github.com> Date: Tue, 7 Jul 2026 14:59:20 +0200 Subject: [PATCH 3/5] Refactor NEWS.md to consolidate bug fixes & inform of silent NA dropping for sparse calculations Removed bug fix section and added duplicate normalization fix under improvements. --- NEWS.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index 5eeda958..ab668a5f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -32,12 +32,6 @@ the dosing including dose amount and route. * 9 volume of distribution at steady state parameters (`vss.*`) * 13 terminal volume of distribution parameters (`vz.*`) -## Bug Fixes - -* `normalize.data.frame()` no longer triggers a dplyr deprecation warning - (`Using 'by = character()' to perform a cross join was deprecated in dplyr 1.1.0`) - when called with ungrouped data (i.e., no common group columns between `object` - and `norm_table`). `dplyr::cross_join()` is now used explicitly for this case. ## Improvements @@ -80,6 +74,12 @@ the dosing including dose amount and route. 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) * `pk.nca` will calculate `fe` and `clr` even if their dependent parameters (e.g, `ae`) were not requested to be calculated in the intervals (#473) +* `normalize.data.frame()` no longer triggers a dplyr deprecation warning + (`Using 'by = character()' to perform a cross join was deprecated in dplyr 1.1.0`) + when called with ungrouped data (i.e., no common group columns between `object` + and `norm_table`). `dplyr::cross_join()` is now used explicitly for this case. +* sparse calculations won't abort with `pk.nca` when the data contains missing (NA) concentrations. It will silently drop them. + ## New features From 31ca5b197c03ffa35d3435cfd48610f39bdbf7da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerardo=20J=2E=20Rodr=C3=ADguez?= <68994823+Gero1999@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:41:01 +0200 Subject: [PATCH 4/5] Remove dplyr deprecation warning note from NEWS.md Updated NEWS.md to remove deprecated warning note for normalize.data.frame(). It was already in another section and should remain there --- NEWS.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 7df5d3a4..5909a527 100644 --- a/NEWS.md +++ b/NEWS.md @@ -99,10 +99,6 @@ the dosing including dose amount and route. 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) * `pk.nca` will calculate `fe` and `clr` even if their dependent parameters (e.g, `ae`) were not requested to be calculated in the intervals (#473) -* `normalize.data.frame()` no longer triggers a dplyr deprecation warning - (`Using 'by = character()' to perform a cross join was deprecated in dplyr 1.1.0`) - when called with ungrouped data (i.e., no common group columns between `object` - and `norm_table`). `dplyr::cross_join()` is now used explicitly for this case. * sparse calculations won't abort with `pk.nca` when the data contains missing (NA) concentrations. It will silently drop them. From b2405576e085ffcc570adcf960c860ccfda7f3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerardo=20J=2E=20Rodr=C3=ADguez?= <68994823+Gero1999@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:41:46 +0200 Subject: [PATCH 5/5] Update NEWS.md and remove empty new line --- NEWS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 5909a527..f147140a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -101,7 +101,6 @@ when the issue is due to an excluded point (#310) * `pk.nca` will calculate `fe` and `clr` even if their dependent parameters (e.g, `ae`) were not requested to be calculated in the intervals (#473) * sparse calculations won't abort with `pk.nca` when the data contains missing (NA) concentrations. It will silently drop them. - ## New features * `pknca_units_table()` is now an S3 generic with a `PKNCAdata` method. When