Skip to content

Commit

Permalink
Merge pull request #118 from generable/pkpd-data-prep
Browse files Browse the repository at this point in the history
Pkpd data prep
  • Loading branch information
jburos authored Feb 28, 2024
2 parents 968c6ff + 62c094b commit a43d7d1
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 38 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Imports:
reticulate,
boot,
cli,
data.table,
httpcache,
keyring
Suggests:
Expand All @@ -45,5 +46,5 @@ Suggests:
scales,
tidyverse,
utils
RoxygenNote: 7.2.3
RoxygenNote: 7.3.1
VignetteBuilder: knitr
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import(keyring)
importFrom(RJSONIO,fromJSON)
importFrom(boot,inv.logit)
importFrom(broom,tidy)
importFrom(data.table,data.table)
importFrom(data.table,setkeyv)
importFrom(dplyr,arrange)
importFrom(dplyr,desc)
importFrom(dplyr,distinct)
Expand Down
1 change: 0 additions & 1 deletion R/rgeco-package.R
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
#'
#' @docType package
#' @name rgeco
NULL

xarray <- NULL

Expand Down
63 changes: 36 additions & 27 deletions R/utils_pkpd.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ fetch_pkpd <- function(project = NULL, project_version_id = NULL, pd_measure = N
pkpd <- prep_pkpd_data(biomarkers_data = b, dose_data = d, pd_measure = pd_measure, pk_measure = pk_measure)
}

.datatable.aware = TRUE

#' Merge and annotate pkpd biomarkers data with dosing data
#' returns a data.frame suitable for plotting and analysis.
#' @param biomarkers_data data.frame containing biomarkers data
#' @param dose_data data.frame containing dose data
#' @param pk_measure measurement_name of PK measurement (defaults to 'conc', NULL indicates no PK marker)
#' @param pd_measure measurement_name of PD measurement (defaults to NULL - no PD marker)
#' @return data.frame containing merged biomarker & dose data for the PK & PD parameter selected, with columns annotating cycles, time since last SDA, and measurement type.
#' @importFrom data.table setkeyv data.table
#' @export
prep_pkpd_data <- function(biomarkers_data, dose_data, pd_measure = NULL, pk_measure = NULL) {
if (nrow(dose_data) == 0) {
Expand All @@ -40,37 +43,43 @@ prep_pkpd_data <- function(biomarkers_data, dose_data, pd_measure = NULL, pk_mea
if (!'start_hours' %in% names(dose_data)) {
stop('dose_data does not have start_hours data. Cannot prepare pkpd data without a formatted start time.')
}
dose_data_renamed <- dose_data %>%
dosesDT <- dose_data %>%
dplyr::rename_at(.vars = dplyr::vars(-.data$subject_id, -.data$drug), .funs = ~ stringr::str_c('dose_', .x)) %>%
dplyr::mutate(hours = .data$dose_start_hours)
if ('collection_timepoint' %in% names(biomarkers_data)) {
merged_data <- biomarkers_data %>%
dplyr::mutate(.dir = dplyr::if_else(.data$collection_timepoint == 'Pre-infusion', 'forward', 'reverse')) %>%
rolling_join(dose_data_renamed,
by = 'subject_id',
on = 'hours',
direction_field = '.dir',
how = 'left',
suffix = c('', '.dose')) %>%
dplyr::select(-.data$hours.dose, -.data$.dir)
} else {
merged_data <- rolling_join(biomarkers_data,
dose_data_renamed,
by = 'subject_id',
on = 'hours',
direction = 'reverse',
how = 'left',
suffix = c('', '.dose')) %>%
dplyr::select(-.data$hours.dose)
}
dplyr::mutate(hours = .data$dose_start_hours) %>%
data.table::data.table()
biomarkersDT <- data.table::data.table(biomarkers_data)
data.table::setkeyv(biomarkersDT, c('subject_id', 'hours'))
data.table::setkeyv(dosesDT, c('subject_id', 'hours'))
# for each PK measurement, identify the dose immediately preceding it
prior_dose <- dosesDT[biomarkersDT, roll = T]
# also identify the next dose
next_dose <- dosesDT[biomarkersDT, roll = -Inf]

## construct final data frame:
# for measurements with a preceding dose, use this as the "closest dose"
with_prior_dose <- prior_dose |>
dplyr::filter(!is.na(.data$dose_dose_id))
# otherwise, use next dose
no_prior_dose <- next_dose |>
dplyr::anti_join(with_prior_dose, by = 'measurement_id')
merged_data <- dplyr::bind_rows(with_prior_dose,
no_prior_dose) |>
dplyr::arrange(subject_id, hours) |>
dplyr::mutate(hours_since_SDA = hours - dose_start_hours)


# merged_data <- rolling_join(biomarkers_data,
# dose_data_renamed,
# by = 'subject_id',
# on = 'hours',
# direction = 'reverse',
# how = 'left',
# suffix = c('', '.dose')) %>%
# dplyr::select(-.data$hours.dose)
if (nrow(merged_data) != nrow(biomarkers_data)) {
futile.logger::flog.warn(glue::glue("Number of records in biomarkers data changed after join, from {nrow(biomarkers_data)} to {nrow(merged_data)}."))
}
pkpd_data <- annotate_pkpd_data(merged_data, pd_measure = pd_measure, pk_measure = pk_measure)
if (nrow(pkpd_data) != nrow(biomarkers_data)) {
futile.logger::flog.warn(glue::glue("Number of records in biomarkers data changed after annotation, from {nrow(biomarkers_data)} to {nrow(pkpd_data)}."))
}
pkpd_data
merged_data
}

#' @importFrom rlang !!
Expand Down
14 changes: 5 additions & 9 deletions man/re-exports.Rd

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

9 changes: 9 additions & 0 deletions man/rgeco.Rd

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

0 comments on commit a43d7d1

Please sign in to comment.