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

Enhancement: NCA for multiple analytes #166

Open
wants to merge 9 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: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ export(geometric_mean)
export(get_label)
export(has_label)
export(lambda_slope_plot)
export(pivot_wider_pknca_results)
export(parse_annotation)
export(parse_tlg_definitions)
export(pivot_wider_pknca_results)
export(pkcg01)
export(pptestcd_dict)
export(run_app)
Expand Down
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
20 changes: 13 additions & 7 deletions R/utils-slope_selector.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@

# 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))))
)
dplyr::filter(TYPE %in% c("Selection", "Exclusion")) %>%
semi_join(
profiles %>%
select(USUBJID, ANALYTE, PCSPEC, DOSNO) %>%
rename(PATIENT = USUBJID, PROFILE = DOSNO),
by = c("PATIENT", "ANALYTE", "PCSPEC", "PROFILE")
) %>%
filter(all(!is.na(sapply(IXrange, function(x) .eval_range(x)))))

if (nrow(slopes) != 0) {
# Go over all rules and check if there is no overlap - if there is, edit accordingly
Expand All @@ -47,6 +49,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 +65,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 +93,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
Loading