Nothing
#' Tracer Selection Diagnostic plot
#'
#' Generates a generalized, faceted point plot to visualize tracer selection
#' metrics across different datasets. Evaluates Classification Rate (CR),
#' Concentration Indicator (CI), and Consistency Error (CONS) against user-defined thresholds.
#'
#' @param data Data frame. Must contain the columns: \code{dataset}, \code{tracer},
#' \code{CR_score}, \code{CI_score}, and \code{consistency_error}. Optionally
#' include a \code{tracer_group} column to facet the plot.
#' @param cr_threshold Numeric. Minimum passing score for CR. Default 70.
#' @param ci_threshold Numeric. Minimum passing score for CI. Default 2.50.
#' @param cons_threshold Numeric. Maximum allowable consistency error. Default 0.025.
#' @param custom_theme A ggplot2 theme object. Defaults to \code{ggplot2::theme_minimal()}.
#'
#' @return A \code{ggplot} object visualizing tracer metric statuses.
#'
#' @import ggplot2
#' @import dplyr
#'
#' @export
tracer_selection_diagnostic_plot <- function(data,
cr_threshold = 70,
ci_threshold = 2.50,
cons_threshold = 0.025,
custom_theme = ggplot2::theme_minimal()) {
# ── 1. Validate Input Data ──────────────────────────────────────────────────
req_cols <- c("dataset", "tracer", "CR_score", "CI_score", "consistency_error")
missing_cols <- setdiff(req_cols, colnames(data))
if (length(missing_cols) > 0) {
stop(sprintf("Input data is missing required column(s): %s", paste(missing_cols, collapse = ", ")))
}
# Assign default grouping if not present
if (!"tracer_group" %in% colnames(data)) {
data$tracer_group <- "All Tracers"
}
# ── 2. Data Preparation ─────────────────────────────────────────────────────
tracer_levels <- unique(as.character(data$tracer))
dataset_levels <- unique(as.character(data$dataset))
plot_df <- data %>%
mutate(
tracer = factor(tracer, levels = tracer_levels),
dataset = factor(dataset, levels = dataset_levels),
tracer_id = as.numeric(tracer),
CR_pass = CR_score > cr_threshold,
CI_pass = CI_score > ci_threshold,
CONS_pass = consistency_error < cons_threshold
)
# Build long format dataframe for dual-metric plotting
cr_df <- plot_df %>%
transmute(
dataset, tracer, tracer_id, tracer_group,
metric = "CR",
pass = CR_pass,
circle_flag = CR_pass & CI_pass & CONS_pass
)
ci_df <- plot_df %>%
transmute(
dataset, tracer, tracer_id, tracer_group,
metric = "CI",
pass = CI_pass,
circle_flag = CR_pass & CI_pass & CONS_pass
)
long_df <- bind_rows(cr_df, ci_df) %>%
mutate(
x = ifelse(metric == "CR", tracer_id + 0.15, tracer_id - 0.15),
color_group = case_when(
metric == "CR" & pass ~ "CR (Pass)",
metric == "CR" & !pass ~ "CR (Fail)",
metric == "CI" & pass ~ "CI (Pass)",
TRUE ~ "CI (Fail)"
)
)
overall_pass_df <- long_df %>%
distinct(dataset, tracer, tracer_group, circle_flag) %>%
filter(circle_flag) %>%
mutate(color_group = "Overall Pass")
# ── 3. Build ggplot ─────────────────────────────────────────────────────────
p <- ggplot(long_df, aes(x = x, y = dataset)) +
# ---- Overall Pass Highlight Circle ----
geom_point(
data = overall_pass_df,
aes(x = as.numeric(tracer), y = dataset, color = color_group),
shape = 21, fill = NA, stroke = 1.2, size = 11
) +
# ---- Individual Metric Status Dots ----
geom_point(
aes(color = color_group),
size = 3.5
) +
# ---- Scales & Aesthetic Definitions ----
scale_x_continuous(
breaks = seq_along(tracer_levels),
labels = tracer_levels,
expand = expansion(add = 0.6)
) +
scale_color_manual(
values = c(
"CR (Pass)" = "forestgreen",
"CR (Fail)" = "tomato",
"CI (Pass)" = "steelblue",
"CI (Fail)" = "orange",
"Overall Pass" = "black"
)
) +
# ---- Native ggplot2 Faceting ----
facet_grid(
. ~ tracer_group,
scales = "free_x",
space = "free_x"
) +
# ---- Theme Customization ----
custom_theme +
labs(
x = "Tracer",
y = "Dataset",
color = "Metric Status"
) +
theme(
axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
legend.position = "bottom",
strip.text.x = element_text(face = "bold", size = 10)
)
return(p)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.