|
#' Returns a beautiful 2x2 density plot grid |
|
#' |
|
#' @param data A data frame |
|
#' @param x The x-axis variable as a string |
|
#' @param group_on A character vector of exactly two variables to use as the |
|
#' rows and columns of the grid in that order |
|
#' @param x_limits A numeric vector of length 2 specifying the min and max values for the x-axis |
|
#' @param title The title — The number of observations will be appended "(n=<n>)" |
|
#' @param scales (optional) scales used in facet wrap (if group_on is provided) |
|
#' @returns A ggplot2 plot |
|
density_grid <- function( |
|
data, |
|
x, |
|
group_on, |
|
x_limits, |
|
title, |
|
scales = "fixed" |
|
) { |
|
data <- data |> group_by(!!as.name(group_on[1]), !!as.name(group_on[2])) |
|
summary <- ( |
|
data |
|
|> summarise( |
|
mean = mean(!!as.name(x)), |
|
median = median(!!as.name(x)), |
|
n = n(), |
|
.groups = "keep" |
|
) |
|
) |
|
|
|
total <- summary |> pull(n) |> sum() |
|
|
|
label_x_position = x_limits[1] + 0.1 * (x_limits[2] - x_limits[1]) |
|
max_y <- ( |
|
data |
|
|> reframe(density = max(density(!!as.name(x))$y)) |
|
|> pull(density) |
|
|> max() |
|
) |
|
|
|
return( |
|
ggplot(data, aes(x = !!as.name(x))) |
|
+ geom_density(alpha = 0.25, fill = "salmon") |
|
+ facet_grid( |
|
rows = vars(!!as.name(group_on[1])), |
|
cols = vars(!!as.name(group_on[2])) |
|
) |
|
+ geom_text( |
|
data = summary, |
|
aes(x = label_x_position, y = max_y * 0.975, label = paste0("n=", n)), |
|
inherit.aes = FALSE, |
|
parse = FALSE |
|
) |
|
+ theme(plot.title = element_text(face = "bold")) |
|
+ scale_x_continuous(expand = expansion(add = 1.05), limits = x_limits) |
|
+ scale_colour_manual( |
|
name = "Summary", |
|
values = c(mean = "red", median = "blue") |
|
) |
|
+ scale_linetype_manual( |
|
name = "Summary", |
|
values = c(mean = "solid", median = "longdash") |
|
) |
|
+ geom_vline( |
|
aes(xintercept = mean, color = "mean", linetype = "mean"), |
|
data = summary |
|
) |
|
+ geom_vline( |
|
aes(xintercept = median, color = "median", linetype = "median"), |
|
data = summary |
|
) |
|
+ labs( |
|
title = paste0(title, " (n=", total, ")"), |
|
color = "Summary", |
|
linetype = "Summary" |
|
) |
|
+ theme(panel.spacing.x = unit(0.75, "lines")) |
|
) |
|
} |