#' Get the impute function from either the intervals column or from the method
#'
#' @param intervals the data.frame of intervals
#' @param impute the imputation definition
#' @return The imputation function vector
get_impute_method <- function(intervals, impute) {
stopifnot(length(impute) == 1)
checkmate::assert_data_frame(intervals)
if (impute %in% names(intervals)) {
impute_funs <- intervals[[impute]]
} else if (is.na(impute) && "impute" %in% names(intervals)) {
impute_funs <- intervals$impute
} else {
impute_funs <- impute
}
checkmate::assert_character(impute_funs)
impute_funs
}
#' Add the imputation column to the intervals, if it is not already there
#'
#' @param object The PKNCAdata object to impute data within
#' @return The PKNCAdata object with an impute column added to the intervals (if
#' it is not already there) and the object$impute set to that column name
#' @keywords internal
add_impute_to_intervals <- function(object) {
if (is.na(object$impute)) {
rlang::abort(
message = "add_impute_to_intervals cannot have an NA imputation defined",
class = "pknca_add_impute_to_intervals_NA"
)
}
# Do nothing if the impute column is already in the data
if (!(object$impute %in% names(object$intervals))) {
impute_col <-
if (!("impute" %in% names(object$intervals))) {
"impute"
} else {
paste0(max(grep(x = names(object$intervals), "^impute", value = TRUE)), "X")
}
object$intervals[[impute_col]] <- object$impute
object$impute <- impute_col
}
object
}
#' Methods for imputation of data with PKNCA
#' @name PKNCA_impute_method
#' @return A data.frame with one column named conc with imputed concentrations
#' 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)
#' @inheritParams pk.calc.auxc
#' @inheritParams assert_intervaltime_single
#' @param ... ignored
#' @export
PKNCA_impute_method_start_conc0 <- function(conc, time, start=0, ..., options = list()) {
ret <- data.frame(conc = conc, time = time)
mask_start <- time %in% start
if (any(mask_start)) {
ret$conc[mask_start] <- 0
} else {
ret <- rbind(ret, data.frame(time = start, conc = 0))
ret <- ret[order(ret$time), ]
}
ret
}
#' @describeIn PKNCA_impute_method Add a new concentration of the minimum during
#' the interval at the start time (usually used with multiple-dose data)
#' @export
PKNCA_impute_method_start_cmin <- function(conc, time, start, end, ..., options = list()) {
ret <- data.frame(conc = conc, time = time)
mask_start <- time %in% start
if (!any(mask_start)) {
all_concs <- conc[start <= time & time <= end]
if (!all(is.na(all_concs))) {
cmin <- min(all_concs, na.rm = TRUE)
ret <- rbind(ret, data.frame(time = start, conc = cmin))
ret <- ret[order(ret$time), ]
}
}
ret
}
#' @describeIn PKNCA_impute_method Shift a predose concentration to become the
#' time zero concentration (only if a time zero concentration does not exist)
#' @param max_shift The maximum amount of time to shift a concentration forward
#' (defaults to 5% of the interval duration, i.e. `0.05*(end - start)`, if
#' `is.finite(end)`, and when `is.infinite(end)`, defaults to 5% of the time
#' from start to `max(time)`)
#' @inheritParams pk.nca.interval
#' @export
PKNCA_impute_method_start_predose <- function(conc, time, start, end, conc.group, time.group, ..., max_shift = NA_real_, options = list()) {
ret <- data.frame(conc = conc, time = time)
if (is.na(max_shift)) {
if (is.infinite(end)) {
shift_end <- max(time)
} else {
shift_end <- end
}
max_shift <- 0.05 * (shift_end - start)
}
# determine if the start time is already in the
mask_start <- time %in% start
if (!any(mask_start)) {
mask_predose <- time.group < start
if (any(mask_predose)) {
time_predose <- max(time.group[mask_predose])
if ((-time_predose) <= max_shift) {
mask_predose_change <- time.group == time_predose
ret_predose <- data.frame(conc = conc.group[mask_predose_change], time = start)
ret <- dplyr::bind_rows(ret_predose, ret)
}
}
}
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.
#'
#' This function is not for use by users of PKNCA.
#'
#' @param x The character vector of PKNCA imputation method functions (without
#' the `PKNCA_impute_method_` part)
#' @return A list of character vectors of functions to run.
#' @keywords Internal
PKNCA_impute_fun_list <- function(x) {
if (all(is.na(x))) {
x <- rep(NA_character_, length(x))
}
ret <- strsplit(x = x, split = "[, ]+", perl = TRUE)
mask_none <- vapply(X = ret, FUN = length, FUN.VALUE = 1L) == 0
ret[mask_none] <- NA_character_
ret <- lapply(X = ret, FUN = PKNCA_impute_fun_list_paste)
# Confirm that the functions exist and are functions
# Sort will ensure that the results are not NA
all_funs <- sort(unlist(ret))
bad_fun <- character()
for (idx in seq_along(all_funs)) {
found_fun <- utils::getAnywhere(all_funs[[idx]])
if (length(found_fun$objs) == 0) {
bad_fun <- c(bad_fun, all_funs[[idx]])
} else if (!is.function(found_fun$objs[[1]])) {
bad_fun <- c(bad_fun, all_funs[[idx]])
}
}
if (length(bad_fun) > 0) {
stop(
"The following imputation functions were not found: ",
paste(bad_fun, collapse = ", ")
)
}
ret
}
# A helper for PKNCA_impute_fun_list that pastes PKNCA_impute_method_ to the
# beginning of everything but NA
PKNCA_impute_fun_list_paste <- function(x) {
mask_paste <- !is.na(x) & !startsWith(x, "PKNCA_impute_method_")
if (any(mask_paste)) {
x[mask_paste] <- paste0("PKNCA_impute_method_", x[mask_paste])
}
x
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.