-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #96 from pharmaverse/bug/individual-plots-grouping
Enhancement: allow to color by multiple variables individual plots
- Loading branch information
Showing
4 changed files
with
189 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
|
||
#' Filter Breaks for X-Axis | ||
#' | ||
#' Filters X-axis for consecutive breaks with at least the specified distance. | ||
#' | ||
#' @param x_breaks A numeric vector of x-axis breaks. | ||
#' @param plot A ggplot object used to extract plot dimensions and scales. | ||
#' @param min_cm_distance A numeric of the minimum distance between breaks. | ||
#' @return A numeric vector of filtered x-axis breaks. | ||
#' @importFrom ggplot2 ggplot_build ggplot_gtable | ||
#' @importFrom grid convertUnit | ||
#' @author Gerardo Rodriguez | ||
#' @export | ||
|
||
filter_breaks <- function(breaks = NA, | ||
plot = plot, | ||
min_cm_distance = 0.5, | ||
axis = "x") { | ||
|
||
breaks <- unique(na.omit(sort(breaks))) | ||
plot_build <- ggplot_build(plot) | ||
plot_table <- ggplot_gtable(plot_build) | ||
|
||
# Extract axis scale information | ||
if (axis == "x") { | ||
scale_range <- plot_build$layout$panel_params[[1]]$x.range | ||
} else if (axis == "y") { | ||
scale_range <- plot_build$layout$panel_params[[1]]$y.range | ||
} else { | ||
stop("Error: Invalid axis specified. Use 'x' or 'y'.") | ||
} | ||
|
||
# Identify the panel grob | ||
panel_index <- which(sapply(plot_table$grobs, | ||
function(x) grepl("panel", x$name))) | ||
|
||
if (length(panel_index) == 0) { | ||
stop("Error: Panel grob not found.") | ||
} | ||
panel <- plot_table$grobs[[panel_index]] | ||
|
||
# Extract the panel border grob to get the width or height | ||
panel_border <- panel$children[[which(sapply(panel$children, | ||
function(x) { | ||
grepl("panel.border", x$name)}))]] | ||
|
||
# Convert panel width or height to cm | ||
if (axis == "x") { | ||
panel_size_cm <- grid::convertUnit(panel_border$width, | ||
unitTo = "cm", | ||
valueOnly = TRUE) | ||
} else { | ||
panel_size_cm <- grid::convertUnit(panel_border$height, | ||
unitTo = "cm", | ||
valueOnly = TRUE) | ||
} | ||
|
||
# Calculate the distance between breaks in cm | ||
break_distances <- diff(breaks) / diff(scale_range) * panel_size_cm | ||
|
||
# Filter only breaks that satisfy the minimum distance | ||
filt_breaks <- breaks[1] | ||
|
||
for (i in 2:length(breaks)) { | ||
|
||
# Take latest selected break and calculate its distance | ||
b0 <- filt_breaks[length(filt_breaks)] | ||
bdist <- (breaks[i] - b0) / diff(scale_range) * panel_size_cm | ||
|
||
if (bdist >= min_cm_distance) { | ||
filt_breaks <- c(filt_breaks, breaks[i]) | ||
} | ||
} | ||
return(filt_breaks) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Sample data for testing | ||
sample_data <- data.frame( | ||
STUDYID = rep("Study1", 24), | ||
USUBJID = rep(c("Subject1", "Subject2", "Subject3", "Subject4"), each = 6), | ||
ANALYTE = rep("Analyte1", 24), | ||
DOSNO = rep(1, 24), | ||
EVID = rep(0, 24), | ||
NRRLT = rep(1:6, 4), | ||
ARRLT = rep(1:6, 4), | ||
ARRLT = rep(1:6, 4), | ||
AVAL = runif(24, 1, 100), | ||
RRLTU = rep("hours", 24), | ||
AVALU = rep("ng/mL", 24), | ||
DOSEA = rep(35, 24) | ||
) | ||
# testthat::test_file("tests/testhat/test-general_lineplot.R") | ||
describe("general_lineplot functions correctly", { | ||
it("returns a ggplot object", { | ||
p <- general_lineplot( | ||
data = sample_data, | ||
selected_analytes = "Analyte1", | ||
selected_usubjids = c("Subject1", "Subject2"), | ||
colorby_var = "DOSNO", | ||
time_scale = "By Cycle", | ||
xaxis_scale = "Linear", | ||
cycle = 1 | ||
) | ||
expect_s3_class(p, "ggplot") | ||
}) | ||
|
||
it("handles empty data gracefully", { | ||
empty_data <- sample_data[0, ] | ||
p <- general_lineplot( | ||
data = empty_data, | ||
selected_analytes = "Analyte1", | ||
selected_usubjids = c("Subject1", "Subject2"), | ||
colorby_var = "DOSNO", | ||
time_scale = "By Cycle", | ||
xaxis_scale = "Linear", | ||
cycle = 1 | ||
) | ||
expect_s3_class(p, "ggplot") | ||
expect_true(length(p$layers) == 0) | ||
}) | ||
|
||
it("handles missing columns gracefully", { | ||
incomplete_data <- sample_data %>% select(-AVAL) | ||
expect_error( | ||
general_lineplot( | ||
data = incomplete_data, | ||
selected_analytes = "Analyte1", | ||
selected_usubjids = c("Subject1", "Subject2"), | ||
colorby_var = "DOSNO", | ||
time_scale = "By Cycle", | ||
xaxis_scale = "Linear", | ||
cycle = 1 | ||
), | ||
"object 'AVAL' not found" | ||
) | ||
}) | ||
|
||
it("can plot with logarithmic scale", { | ||
p <- general_lineplot( | ||
data = sample_data, | ||
selected_analytes = "Analyte1", | ||
selected_usubjids = c("Subject1", "Subject2"), | ||
colorby_var = "DOSNO", | ||
time_scale = "By Cycle", | ||
xaxis_scale = "Log", | ||
cycle = 1 | ||
) | ||
expect_s3_class(p, "ggplot") | ||
|
||
# Check for logarithmic scale in the plot | ||
is_log_scale <- grepl("log", p$scales$scales[[1]]$trans$name) | ||
expect_true(is_log_scale) | ||
}) | ||
}) |