From cd8cbd6328a029a61c311b7a524ec88e694e4a6c Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Mon, 23 Mar 2026 00:07:05 -0400 Subject: [PATCH 1/7] Release preparation for version 0.12.2 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 7f205259..a295575a 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: PKNCA Type: Package Title: Perform Pharmacokinetic Non-Compartmental Analysis -Version: 0.12.1.9000 +Version: 0.12.2 Authors@R: c( person("Bill", "Denney", email="wdenney@humanpredictions.com", role=c("aut", "cre"), comment=c(ORCID="0000-0002-5759-428X")), person("Clare", "Buckeridge", email="clare.buckeridge@pfizer.com", role="aut"), From b0d0883a42485dff14b85892c62101f9c8b22555 Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Mon, 23 Mar 2026 00:08:46 -0400 Subject: [PATCH 2/7] Release preparation for version 0.12.2 --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index b5f124ed..eb6d336f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,7 +4,7 @@ will continue until then. These will be especially noticeable around the inclusion of IV NCA parameters and additional specifications of the dosing including dose amount and route. -# Development version +# PKNCA 0.12.2 ## Breaking changes From e1ff6ecbf71c7cdcf8d33fb0c59f701949d473d6 Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Mon, 23 Mar 2026 06:28:07 -0400 Subject: [PATCH 3/7] perf: reduce data.frame construction overhead in hot paths (~10% speedup) Three targeted improvements with no functionality change: 1. pk.calc.half.life: pre-build the two-column data.frame passed to fit_half_life() once before the loop rather than reconstructing it on every iteration. For a subject with N eligible post-tmax points this reduces data.frame() calls in that loop from N to 1. 2. pk.nca.intervals: accumulate interval results in a list and combine with dplyr::bind_rows() at the end instead of growing a data.frame via repeated rbind(). For analyses with multiple dosing intervals per subject the old pattern caused quadratic copy overhead. 3. pk.nca.intervals: hoist the PKNCA.options()$debug lookup out of the per-interval loop. The options object passed in is already the fully-merged options (assembled once in pk.nca()), so there is no need to re-query the package environment on every iteration. Benchmarked on 200 subjects x 12 time points x 10 reps (single interval, auclast/cmax/tmax/half.life/tlast): median 2.46s -> 2.23s (~10% faster). The rbind fix provides additional gains for multi-interval analyses. Co-Authored-By: Claude Sonnet 4.6 --- R/half.life.R | 18 +++++++++--------- R/pk.calc.all.R | 12 ++++++++---- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/R/half.life.R b/R/half.life.R index c2092cff..ce777082 100644 --- a/R/half.life.R +++ b/R/half.life.R @@ -212,18 +212,18 @@ pk.calc.half.life <- function(conc, time, tmax, tlast, ) half_lives_for_selection <- half_lives_for_selection[order(-half_lives_for_selection$lambda.z.time.first), ] + # Pre-build the two-column data.frame that fit_half_life expects. The rows + # are already in descending-time order (matching half_lives_for_selection). + # Subsetting a pre-built data.frame avoids constructing a new data.frame on + # every loop iteration. + dfK_for_fit <- data.frame( + log_conc = half_lives_for_selection$log_conc, + time = half_lives_for_selection$lambda.z.time.first + ) for(i in min.hl.points:nrow(half_lives_for_selection)) { # Fit the terminal slopes until the adjusted r-squared value # is not improving (or it only gets worse by a small factor). - fit <- - fit_half_life( - data= - data.frame( - log_conc=half_lives_for_selection$log_conc[1:i], - time=half_lives_for_selection$lambda.z.time.first[1:i] - ), - tlast=ret$tlast - ) + fit <- fit_half_life(data=dfK_for_fit[seq_len(i), , drop=FALSE], tlast=ret$tlast) half_lives_for_selection[i,names(fit)] <- fit } # Find the best model diff --git a/R/pk.calc.all.R b/R/pk.calc.all.R index 0ad89806..52d12364 100644 --- a/R/pk.calc.all.R +++ b/R/pk.calc.all.R @@ -196,7 +196,11 @@ pk.nca.intervals <- function(data_conc, data_dose, data_intervals, sparse, # No intervals; potentially placebo data return(rlang::warning_cnd(class="pknca_no_intervals", message="No intervals for data")) } - ret <- data.frame() + # Hoist the debug check: options is already the fully-merged options object + # (merged at the top of pk.nca()), so there is no need to re-query + # PKNCA.options() from the environment on every iteration. + use_debug <- !is.null(options$debug) + ret_list <- list() for (i in seq_len(nrow(data_intervals))) { current_interval <- data_intervals[i, , drop=FALSE] has_calc_sparse_dense <- any_sparse_dense_in_interval(current_interval, sparse=sparse) @@ -279,7 +283,7 @@ pk.nca.intervals <- function(data_conc, data_dose, data_intervals, sparse, stop("Cannot both include and exclude half-life points for the same interval") } # Try the calculation - if (!is.null(PKNCA.options()$debug)) { + if (use_debug) { # debugging mode does not need coverage calculated_interval <- do.call(pk.nca.interval, args) # nocov } else { @@ -304,10 +308,10 @@ pk.nca.intervals <- function(data_conc, data_dose, data_intervals, sparse, calculated_interval, row.names=NULL ) - ret <- rbind(ret, new_ret) + ret_list[[length(ret_list) + 1L]] <- new_ret } } - ret + if (length(ret_list) == 0L) data.frame() else dplyr::bind_rows(ret_list) } #' Compute all PK parameters for a single concentration-time data set From 8f0b4e98c5ee5f452c897e32157f5819e1006e6c Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Mon, 23 Mar 2026 07:06:30 -0400 Subject: [PATCH 4/7] As submitted to CRAN --- CRAN-SUBMISSION | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION index c6820392..b58e5d37 100644 --- a/CRAN-SUBMISSION +++ b/CRAN-SUBMISSION @@ -1,3 +1,3 @@ -Version: 0.12.1 -Date: 2025-08-19 00:38:37 UTC -SHA: 68c5803de01dfc6cc8e43cfdf649de69e38b2a85 +Version: 0.12.2 +Date: 2026-03-23 11:06:19 UTC +SHA: e1ff6ecbf71c7cdcf8d33fb0c59f701949d473d6 From 1429dbeb356756c8979c54e979890c78ad5374b2 Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Mon, 23 Mar 2026 09:34:05 -0400 Subject: [PATCH 5/7] fix: correct invalid file URI in v01 vignette Replace [Quick Start](Quick Start) with [Quick Start](#quick-start) to produce a valid in-document anchor rather than a file URI, resolving the CRAN NOTE about an invalid file URI in inst/doc/v01-introduction-and-usage.html. Co-Authored-By: Claude Sonnet 4.6 --- vignettes/v01-introduction-and-usage.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/v01-introduction-and-usage.Rmd b/vignettes/v01-introduction-and-usage.Rmd index 4235af48..1362c1d3 100644 --- a/vignettes/v01-introduction-and-usage.Rmd +++ b/vignettes/v01-introduction-and-usage.Rmd @@ -408,7 +408,7 @@ minimum-required number of calculations for the data that are changed. To use `update()`, give it your existing results and the new `PKNCAdata` object you want to use. -Starting from the theophylline example in the [Quick Start](Quick Start) section above: +Starting from the theophylline example in the [Quick Start](#quick-start) section above: ```{r update-example-setup} d_conc <- as.data.frame(datasets::Theoph) From 3c048da92711ddc75d121a3c654073e20878b132 Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Mon, 23 Mar 2026 09:36:43 -0400 Subject: [PATCH 6/7] Note URI fix --- cran-comments.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 cran-comments.md diff --git a/cran-comments.md b/cran-comments.md new file mode 100644 index 00000000..09276f4f --- /dev/null +++ b/cran-comments.md @@ -0,0 +1,5 @@ +## R CMD check results + +0 errors | 0 warnings | 1 note + +* Fixed URI error noted in prior submission From b3dddee748e7a8e5f48d0c09b443cb82e949861b Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Mon, 23 Mar 2026 10:03:54 -0400 Subject: [PATCH 7/7] As submitted to CRAN --- CRAN-SUBMISSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION index b58e5d37..cf37464f 100644 --- a/CRAN-SUBMISSION +++ b/CRAN-SUBMISSION @@ -1,3 +1,3 @@ Version: 0.12.2 -Date: 2026-03-23 11:06:19 UTC -SHA: e1ff6ecbf71c7cdcf8d33fb0c59f701949d473d6 +Date: 2026-03-23 14:03:31 UTC +SHA: 3c048da92711ddc75d121a3c654073e20878b132