Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: New logslope & c1 impute_start methods #350 #351

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ export(PKNCA.choose.option)
export(PKNCA.options)
export(PKNCA.options.describe)
export(PKNCA.set.summary)
export(PKNCA_impute_method_start_c1)
export(PKNCA_impute_method_start_cmin)
export(PKNCA_impute_method_start_conc0)
export(PKNCA_impute_method_start_logslope)
export(PKNCA_impute_method_start_predose)
export(PKNCAconc)
export(PKNCAdata)
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ the dosing including dose amount and route.

# PKNCA 0.11.0.9000

* New default PKNCA impute start methods for C1 and IV bolus logslope to add for intervals without a start concentration
* PKNCA options can now use `tmax` as a reference for BLQ handling by using new names in the `conc.blq` argument (`before.tmax`,`after.tmax`)
* PKNCA will now give an error when there are unexpected interval columns.
The `keep_interval_cols` option can be used to mitigate this error.
Expand Down
40 changes: 40 additions & 0 deletions R/impute.R
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,46 @@ PKNCA_impute_method_start_predose <- function(conc, time, start, end, conc.group
ret
}

#' @describeIn PKNCA_impute_method Imputes based on a logarithmic slope on the
#' first points a time zero concentration (usually in IV bolus at dose time)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an additional part to the description: "If this imputation is used for NCA calculations, back-extrapolation percent will not be calculated or will be calculated as zero."

#' @export
PKNCA_impute_method_start_logslope <- function(conc, time, start, end, ..., options = list()) { # nolint

ret <- data.frame(conc = conc, time = time)
mask_start <- time %in% start
if (!any(mask_start)) {
all_concs <- conc[time >= start & time <= end]
all_times <- time[time >= start & time <= end]
if (!all(is.na(all_concs))) {
c0 <- PKNCA::pk.calc.c0(all_concs, all_times, method = "logslope")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is within PKNCA, please switch to the pk.calc.c0.method.logslope function directly rather than using pk.calc.c0.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please set time.dose = start in case the intended start time is not 0. Please add a test for this case as well.

if (!is.na(c0)) {
ret <- rbind(ret, data.frame(time = start, conc = c0))
ret <- ret[order(ret$time), ]
}
}
}
ret
}

#' @describeIn PKNCA_impute_method Shift the following concentration to a start
#' to become the time zero concentration (rarely used; non-monodecay IV bolus)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an additional part to the description: "If this imputation is used for NCA calculations, back-extrapolation percent will not be calculated or will be calculated as zero."

#' @return A data frame with imputed start concentration.
#' @export
PKNCA_impute_method_start_c1 <- function(conc, time, start, end, ..., options = list()) { # nolint
ret <- data.frame(conc = conc, time = time)
mask_start <- time %in% start
if (!any(mask_start)) {
all_concs <- conc[time >= start & time <= end]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use pk.calc.c0.method.c1. That way, you don't need to filter all_concs, all_times, and your is.na() test below can be on c1. That will also ensure that c1 is consistently calculated anywhere it is used within PKNCA.

all_times <- time[time >= start & time <= end]
if (!all(is.na(all_concs))) {
c1 <- all_concs[which.min(all_times)]
ret <- rbind(ret, data.frame(time = start, conc = c1))
ret <- ret[order(ret$time), ]
}
}
ret
}

#' Separate out a vector of PKNCA imputation methods into a list of functions
#'
#' An error will be raised if the functions are not found.
Expand Down
21 changes: 21 additions & 0 deletions man/PKNCA_impute_method.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions tests/testthat/test-impute.R
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,58 @@ test_that("PKNCA_impute_method_start_cmin", {

})

test_that("PKNCA_impute_method_start_logslope", {
# No imputation when start is in the data
expect_equal(
PKNCA_impute_method_start_logslope(conc = 3:1, time = 0:2, start = 0, end = 2),
data.frame(conc = 3:1, time = 0:2)
)
# Impute when start is not in the data
expect_equal(
PKNCA_impute_method_start_logslope(conc = 3:1, time = 1:3, start = 0, end = 3),
data.frame(conc = c(4.5, 3:1), time = 0:3),
ignore_attr = TRUE
)
# Data outside the interval are ignored (before interval)
expect_equal(
PKNCA_impute_method_start_logslope(conc = c(0, 2:1), time = c(-1, 1:2), start = 0, end = 2),
data.frame(conc = c(0, 4, 2:1), time = c(-1, 0, 1:2)),
ignore_attr = TRUE
)
# No modification if no C1 -> C2 decline in samples
expect_equal(
PKNCA_impute_method_start_logslope(conc = c(1, 1, 1), time = 1:3, start = 0, end = 3),
data.frame(conc = c(1, 1, 1), time = 1:3),
ignore_attr = TRUE
)
# No modification if C1 = C2 in samples
expect_equal(
PKNCA_impute_method_start_logslope(conc = c(3, 3, 1), time = 1:3, start = 0, end = 3),
data.frame(conc = c(3, 3, 1), time = 1:3),
ignore_attr = TRUE
)
})
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add tests for:

  1. All concentrations are NA
  2. All times are NA
  3. All concentrations are 0

(I see that list of tests is needed for the other imputation methods, too. I just added an issue, #361, to add those after this PR is merged.)


test_that("PKNCA_impute_method_start_c1", {
# No imputation when start is in the data
expect_equal(
PKNCA_impute_method_start_c1(conc = 1:3, time = 0:2, start = 0, end = 2),
data.frame(conc = 1:3, time = 0:2)
)
# Impute when start is not in the data
expect_equal(
PKNCA_impute_method_start_c1(conc = 1:3, time = 1:3, start = 0, end = 3),
data.frame(conc = c(1, 1:3), time = 0:3),
ignore_attr = TRUE
)
# Data outside the interval are ignored (before interval)
expect_equal(
PKNCA_impute_method_start_c1(conc = 1:3, time = c(-1, 1:2), start = 0, end = 2),
data.frame(conc = c(1, 2, 2:3), time = c(-1, 0, 1:2)),
ignore_attr = TRUE
)
})

test_that("PKNCA_impute_fun_list", {
expect_equal(
PKNCA_impute_fun_list(NA_character_),
Expand Down
Loading