Skip to content
Merged
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
13 changes: 10 additions & 3 deletions R/impute.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,16 @@ get_impute_method <- function(intervals, impute) {
#' and one column named time with the times.
NULL

#' @describeIn PKNCA_impute_method Add a new concentration of 0 at the start
#' time, even if a nonzero concentration exists at that time (usually used
#' with single-dose data)
#' @describeIn PKNCA_impute_method Set the concentration at the start time to
#' 0, even if a nonzero concentration exists at that time (usually used with
#' single-dose data). Forcing the start concentration to zero is
#' intentional: an existing start-time value is replaced with 0, including
#' a nonzero predose measurement shifted to the start time by
#' `start_predose`, so the imputation chain `"start_predose,start_conc0"`
#' gives the same result as `"start_conc0"` alone. To carry a predose
#' measurement to the start time, use `start_predose` without
#' `start_conc0`. When no observation exists at the start time, a new row
#' with a concentration of 0 is added.
#' @inheritParams pk.calc.auxc
#' @inheritParams assert_intervaltime_single
#' @param ... ignored
Expand Down
13 changes: 10 additions & 3 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 @@ -18,6 +18,58 @@ test_that("PKNCA_impute_method_start_conc0", {
)
})

test_that("start_conc0 intentionally replaces an existing start concentration with 0 (#578)", {
# A nonzero concentration at the start time is forced to 0
expect_equal(
PKNCA_impute_method_start_conc0(conc = c(5, 2, 3), time = 0:2),
data.frame(conc = c(0, 2, 3), time = 0:2)
)
# The replacement also occurs at a nonzero start time
expect_equal(
PKNCA_impute_method_start_conc0(conc = 1:3, time = 0:2, start = 1),
data.frame(conc = c(1, 0, 3), time = 0:2)
)
})

test_that("start_predose,start_conc0 collapses to start_conc0 by design (#578)", {
# A predose sample within max_shift (5% of the 0-24 interval, so within 1.2)
d_conc <-
data.frame(
subject = 1,
time = c(-0.5, 1, 2, 4, 8, 12, 24),
conc = c(2, 5, 4, 3, 2.5, 2, 1)
)
o_conc <- PKNCAconc(d_conc, conc~time|subject)
d_intervals <- data.frame(start = 0, end = 24, auclast = TRUE)
get_auclast <- function(impute) {
o_data <- suppressMessages(PKNCAdata(o_conc, intervals = d_intervals, impute = impute))
d_res <- as.data.frame(suppressMessages(pk.nca(o_data)))
d_res$PPORRES[d_res$PPTESTCD == "auclast"]
}
auclast_chain <- get_auclast("start_predose,start_conc0")
auclast_conc0 <- get_auclast("start_conc0")
auclast_predose <- get_auclast("start_predose")
# start_conc0 replaces the concentration that start_predose shifted to the
# start time, so the chain gives the same result as start_conc0 alone
expect_equal(auclast_chain, auclast_conc0)
expect_equal(
auclast_chain,
as.numeric(pk.calc.auc.last(
conc = c(0, 5, 4, 3, 2.5, 2, 1),
time = c(0, 1, 2, 4, 8, 12, 24)
))
)
# start_predose alone carries the predose concentration to the start time
expect_equal(
auclast_predose,
as.numeric(pk.calc.auc.last(
conc = c(2, 5, 4, 3, 2.5, 2, 1),
time = c(0, 1, 2, 4, 8, 12, 24)
))
)
expect_true(auclast_predose != auclast_conc0)
})

test_that("PKNCA_impute_method_start_predose", {
# No modification if no predose samples
expect_equal(
Expand Down
23 changes: 13 additions & 10 deletions vignettes/v08-data-imputation.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,19 @@ use, give the `[method name]` part of the function name. So for the example
above, use `"start_conc0"`.

To specify more than one, give all the methods in order with a comma or space
separating them. For example, to first move a predose concentration up to the
time of dosing and then set time 0 to concentration 0, use
`"start_predose,start_conc0"`, and the two methods will be applied in order,
each to the output of the previous method. Note that because `start_conc0`
sets the start-time concentration to 0 even when a start-time value already
exists, the `"start_predose,start_conc0"` chain produces the same results as
`"start_conc0"` alone: the concentration that `start_predose` shifts to the
start time is then overwritten with 0. To use the predose concentration when
one exists and 0 otherwise, write a custom imputation method (see the
"Advanced" section below).
separating them (for example, `"start_predose,start_conc0"`), and the methods
will be applied in order, each to the output of the previous method. Note
that because `start_conc0` sets the start-time concentration to 0 even when a
start-time value already exists, the `"start_predose,start_conc0"` chain
produces the same results as `"start_conc0"` alone: the concentration that
`start_predose` shifts to the start time is then overwritten with 0. This
overwriting is by design; the intent of `start_conc0` is to force the start
concentration to zero, and that can remove a nonzero predose concentration,
too. To carry a predose concentration to the start time, use
`"start_predose"` alone; to force the start concentration to zero, use
`"start_conc0"`; and to use the predose concentration when one exists and 0
otherwise, write a custom imputation method (see the "Advanced" section
below).

## Imputation for the full dataset

Expand Down