Skip to content

Commit

Permalink
Merge pull request #166 from pharmaverse/enhancement/multiple-analytes
Browse files Browse the repository at this point in the history
Enhancement: NCA for multiple analytes
  • Loading branch information
js3110 authored Jan 23, 2025
2 parents 75feaea + 38c3e45 commit 39ea9f1
Show file tree
Hide file tree
Showing 17 changed files with 1,369 additions and 96 deletions.
7 changes: 6 additions & 1 deletion R/format_data.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ format_pkncaconc_data <- function(ADNCA, group_columns, time_column = "AFRLT") {
#'
#' This function creates a pharmacokinetic dose dataset from the provided concentration data.
#'
#' @param ADNCA_conc A data frame containing the concentration data.
#' @param pkncaconc_data A data frame containing the concentration data.
#' @param group_columns A character vector specifying the columns to group by.
#' @param dosno_column A character string specifying the dose number column.
#' @param time_column A character string specifying the time column.
#' @param since_lastdose_time_column A character string specifying the time since last dose column.
#'
#' @returns A data frame containing the dose data.
#'
Expand Down Expand Up @@ -93,6 +97,7 @@ format_pkncadose_data <- function(pkncaconc_data,
slice(1) %>%
ungroup() %>%
arrange(!!!syms(group_columns))

}

#' Create Dose Intervals Dataset
Expand Down
16 changes: 12 additions & 4 deletions R/general_lineplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#'
#' @param data A data frame containing the ADNCA dataset.
#' @param selected_analytes A character vector of selected analytes to be included in the plot.
#' @param selected_pcspec A character vector of selected matrix to be included in the plot.
#' @param selected_usubjids A character vector of selected unique subject identifiers (USUBJIDs)
#' to be included in the plot.
#' @param colorby_var A character string specifying the variable by which to color
Expand All @@ -22,7 +23,7 @@
#' @details
#' The function performs the following steps:a
#' \itemize{
#' \item Filters the data based on the selected analytes and subjects.
#' \item Filters the data based on the selected analytes, matrices, and subjects.
#' \item Selects relevant columns and removes rows with missing concentration values.
#' \item Converts 'USUBJID', 'DOSNO', and 'DOSEA' to factors.
#' \item Filters the data by cycle if `time_scale` is "By Cycle".
Expand All @@ -36,6 +37,7 @@
#' # Example usage:
#' plot <- general_lineplot(data = adnca_data,
#' selected_analytes = c("Analyte1", "Analyte2"),
#' selected_pcspec = c("Spec1", "Spec2"),
#' selected_usubjids = c("Subject1", "Subject2"),
#' colorby_var = "DOSNO",
#' time_scale = "By Cycle",
Expand All @@ -50,7 +52,8 @@
#' @importFrom tern g_ipp
#' @export
general_lineplot <- function(
data, selected_analytes, selected_usubjids, colorby_var, time_scale, yaxis_scale, cycle = NULL
data, selected_analytes, selected_pcspec, selected_usubjids,
colorby_var, time_scale, yaxis_scale, cycle = NULL
) {

# Check if the data is empty
Expand All @@ -63,6 +66,7 @@ general_lineplot <- function(
filter(
USUBJID %in% selected_usubjids,
ANALYTE %in% selected_analytes,
PCSPEC %in% selected_pcspec,
if ("EVID" %in% names(data)) EVID == 0 else TRUE
) %>%
filter(!is.na(AVAL)) %>%
Expand All @@ -72,6 +76,10 @@ general_lineplot <- function(
DOSEA = factor(DOSEA),
id_var = interaction(!!!syms(colorby_var), sep = ", ")
)
# Check if the data is empty
if (nrow(preprocessed_data) == 0) {
return(ggplot() + ggtitle("No data available for selected parameters"))
}

# If there are predose records duplicate them in the previous line so they are considered
if ("ARRLT" %in% names(preprocessed_data) &&
Expand Down Expand Up @@ -125,8 +133,8 @@ general_lineplot <- function(
subtitle = paste0(
"Subjects: ",
paste(unique(preprocessed_data$USUBJID), collapse = ", "),
"\nAnalyte: ",
unique(preprocessed_data$ANALYTE)
"\nAnalyte(s): ",
paste(unique(preprocessed_data$ANALYTE), collapse = ", ")
),
caption = NULL,
add_baseline_hline = FALSE,
Expand Down
5 changes: 4 additions & 1 deletion R/general_meanplot.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#' @param data A data frame containing the ADNCA dataset.
#' @param selected_studyids A character vector of selected study IDs to be included in the plot.
#' @param selected_analytes A character vector of selected analytes to be included in the plot.
#' @param selected_pcspecs A character vector of selected matrices to be included in the plot.
#' @param selected_cycles A character vector or numeric vector of selected cycles to be
#' included in the plot.
#' @param id_variable A character string specifying the variable by which to color the lines
Expand All @@ -28,6 +29,7 @@
general_meanplot <- function(data,
selected_studyids,
selected_analytes,
selected_pcspecs,
selected_cycles,
id_variable = "DOSEA",
plot_ylog = FALSE,
Expand All @@ -39,6 +41,7 @@ general_meanplot <- function(data,
filter(
STUDYID %in% selected_studyids,
ANALYTE %in% selected_analytes,
PCSPEC %in% selected_pcspecs,
DOSNO %in% selected_cycles,
if ("EVID" %in% names(data)) EVID == 0 else TRUE,
NRRLT > 0
Expand All @@ -50,7 +53,7 @@ general_meanplot <- function(data,
summarised_data <- preprocessed_data %>%
mutate(id_variable = as.factor(!!sym(id_variable))) %>%
# Create a groups variables for the labels
mutate(groups = paste(STUDYID, ANALYTE, DOSNO, sep = ", ")) %>%
mutate(groups = paste(STUDYID, ANALYTE, PCSPEC, DOSNO, sep = ", ")) %>%
group_by(id_variable, NRRLT, groups) %>%
summarise(
Mean = round(mean(AVAL, na.rm = TRUE), 3),
Expand Down
21 changes: 15 additions & 6 deletions R/lambda_slope_plot.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#' @param conc_pknca_df Data frame containing the concentration data
#' (default is `mydata$conc$data`).
#' @param dosno Numeric value representing the dose number (default is `profile`).
#' @param analyte Character value representing the analyte (default is `analyte`).
#' @param pcspec Character value representing the matrix (default is `pcspec`).
#' @param usubjid Character value representing the unique subject identifier
#' (default is `patient`).
#' @param R2ADJTHRESHOL Numeric value representing the R-squared adjusted threshold for determining
Expand Down Expand Up @@ -37,6 +39,8 @@
#' # Example usage:
#' plot <- lambda_slope_plot(res_pknca_df = myres$result,
#' conc_pknca_df = mydata$conc$data,
#' analyte = "analyte_1",
#' pcspec = "pcspec_1",
#' dosno = 1,
#' usubjid = "subject_1",
#' R2ADJTHRESHOL = 0.7)
Expand All @@ -52,14 +56,17 @@ lambda_slope_plot <- function(
conc_pknca_df = mydata$conc$data,
dosno = profile,
usubjid = patient,
analyte = analyte,
pcspec = pcspec,
R2ADJTHRESHOL = 0.7
) {

# Obtain all information relevant regarding lambda calculation
lambda_res <- res_pknca_df %>%
filter(DOSNO == dosno, USUBJID == usubjid, type_interval == "main") %>%
arrange(USUBJID, DOSNO, start, desc(end)) %>%
filter(!duplicated(paste0(USUBJID, DOSNO, PPTESTCD)))
filter(DOSNO == dosno, USUBJID == usubjid, ANALYTE == analyte,
PCSPEC == pcspec, type_interval == "main") %>%
arrange(USUBJID, DOSNO, ANALYTE, PCSPEC, start, desc(end)) %>%
filter(!duplicated(paste0(USUBJID, DOSNO, PCSPEC, ANALYTE, PPTESTCD)))

# Obtain the number of data points used to calculate lambda
lambda_z_n_points <- as.numeric(lambda_res$PPORRES[lambda_res$PPTESTCD == "lambda.z.n.points"])
Expand Down Expand Up @@ -141,7 +148,7 @@ lambda_slope_plot <- function(

# Include in the data the aesthetics for the plot
plot_data <- conc_pknca_df %>%
filter(DOSNO == dosno, USUBJID == usubjid) %>%
filter(DOSNO == dosno, USUBJID == usubjid, ANALYTE == analyte, PCSPEC == pcspec) %>%
arrange(IX) %>%
mutate(
IX_shape = ifelse(is.excluded.hl, "excluded", "included"),
Expand Down Expand Up @@ -174,7 +181,8 @@ lambda_slope_plot <- function(
size = 5
) +
labs(
title = paste0("USUBJID: ", usubjid, ", DOSNO: ", dosno),
title = paste0("USUBJID: ", usubjid, ", DOSNO: ", dosno,
", ANALYTE: ", analyte, ", PCSPEC: ", pcspec),
y = paste0("Log10 Concentration (", conc_pknca_df $PCSTRESU[1], ")"),
x = paste0("Actual time post dose (", conc_pknca_df $RRLTU[1], ")")
) +
Expand Down Expand Up @@ -229,7 +237,8 @@ lambda_slope_plot <- function(
pl <- pl %>%
# Make this trace the only one
add_trace(
data = plot_data %>% filter(DOSNO == dosno, USUBJID == usubjid),
data = plot_data %>% filter(DOSNO == dosno, USUBJID == usubjid,
ANALYTE == analyte, PCSPEC == pcspec),
x = ~TIME, y = ~log10(AVAL),
customdata = ~paste0(USUBJID, "_", DOSNO, "_", IX),
text = ~paste0("Data Point: ", IX, "\n", "(", signif(TIME, 2), " , ", signif(AVAL, 2), ")"),
Expand Down
18 changes: 11 additions & 7 deletions R/utils-slope_selector.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@

# Eliminate all rows with conflicting or blank values
slopes <- slopes %>%
dplyr::filter(
TYPE %in% c("Selection", "Exclusion"),
PATIENT %in% names(profiles),
PROFILE %in% unname(unlist(profiles[PATIENT])),
all(!is.na(sapply(IXrange, function(x) .eval_range(x))))
)
filter(TYPE %in% c("Selection", "Exclusion")) %>%
semi_join(
select(profiles, USUBJID, ANALYTE, PCSPEC, DOSNO),
by = c("PATIENT" = "USUBJID", "ANALYTE", "PCSPEC", "PROFILE" = "DOSNO")
) %>%
filter(all(!is.na(sapply(IXrange, .eval_range))))

if (nrow(slopes) != 0) {
# Go over all rules and check if there is no overlap - if there is, edit accordingly
Expand All @@ -47,6 +47,8 @@
for (i in seq_len(nrow(slopes))) {
selection_index <- which(
data$conc$data$USUBJID == slopes$PATIENT[i] &
data$conc$data$ANALYTE == slopes$ANALYTE[i] &
data$conc$data$PCSPEC == slopes$PCSPEC[i] &
data$conc$data$DOSNO == slopes$PROFILE[i] &
data$conc$data$IX %in% .eval_range(slopes$IXrange[i])
)
Expand All @@ -61,7 +63,7 @@
}

data$conc$data <- data$conc$data %>%
dplyr::group_by(STUDYID, USUBJID, PCSPEC, DOSNO) %>%
dplyr::group_by(STUDYID, USUBJID, ANALYTE, PCSPEC, DOSNO) %>%
dplyr::mutate(exclude_half.life = {
if (any(is.included.hl)) {
is.excluded.hl | !is.included.hl
Expand Down Expand Up @@ -89,6 +91,8 @@
existing_index <- which(
existing$TYPE == new$TYPE &
existing$PATIENT == new$PATIENT &
existing$ANALYTE == new$ANALYTE &
existing$PCSPEC == new$PCSPEC &
existing$PROFILE == new$PROFILE
)

Expand Down
Loading

0 comments on commit 39ea9f1

Please sign in to comment.