From 001c7a6b98868cd35cbfbbf06caf987955c034d7 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Sun, 24 Aug 2025 10:43:23 -0400 Subject: [PATCH 01/14] fix arg names --- R/check_ess.R | 32 ++++---- R/geom_calibration.R | 34 ++++---- R/plot_calibration.R | 18 ++--- R/plot_ess.R | 24 +++--- R/plot_qq.R | 14 ++-- R/utils.R | 2 +- man/check_ess.Rd | 24 +++--- man/check_model_calibration.Rd | 4 +- man/geom_calibration.Rd | 12 +-- man/plot_ess.Rd | 30 +++---- man/plot_model_calibration.Rd | 6 +- man/plot_qq.Rd | 4 +- tests/testthat/_snaps/check_ess.md | 2 +- tests/testthat/_snaps/error-messages.md | 2 +- .../plot-calibration-glm-with-rug.svg | 78 +++++++++---------- .../plot-calibration-lm-logistic-with-rug.svg | 78 +++++++++---------- tests/testthat/_snaps/plot_qq.md | 2 +- tests/testthat/test-check_ess.R | 12 +-- tests/testthat/test-geom_calibration.R | 28 +++---- tests/testthat/test-plot_ess.R | 8 +- 20 files changed, 207 insertions(+), 207 deletions(-) diff --git a/R/check_ess.R b/R/check_ess.R index 9f50746..39190ff 100644 --- a/R/check_ess.R +++ b/R/check_ess.R @@ -12,7 +12,7 @@ #' number of observations, indicating that a few observations carry #' disproportionately large weights. #' -#' When `.group` is provided, ESS is calculated separately for each group level: +#' When `.exposure` is provided, ESS is calculated separately for each exposure level: #' - For binary/categorical exposures: ESS is computed within each treatment level #' - For continuous exposures: The variable is divided into quantiles (using #' `dplyr::ntile()`) and ESS is computed within each quantile @@ -21,17 +21,17 @@ #' further analysis. #' #' @inheritParams check_params -#' @param .group Optional grouping variable. When provided, ESS is calculated -#' separately for each group level. For continuous variables, groups are +#' @param .exposure Optional exposure variable. When provided, ESS is calculated +#' separately for each exposure level. For continuous variables, groups are #' created using quantiles. -#' @param n_tiles For continuous `.group` variables, the number of quantile +#' @param n_tiles For continuous `.exposure` variables, the number of quantile #' groups to create. Default is 4 (quartiles). #' @param tile_labels Optional character vector of labels for the quantile groups -#' when `.group` is continuous. If NULL, uses "Q1", "Q2", etc. +#' when `.exposure` is continuous. If NULL, uses "Q1", "Q2", etc. #' #' @return A tibble with columns: #' \item{method}{Character. The weighting method ("observed" or weight variable name).} -#' \item{group}{Character. The group level (if `.group` is provided).} +#' \item{group}{Character. The exposure level (if `.exposure` is provided).} #' \item{n}{Integer. The number of observations in the group.} #' \item{ess}{Numeric. The effective sample size.} #' \item{ess_pct}{Numeric. ESS as a percentage of the actual sample size.} @@ -44,27 +44,27 @@ #' check_ess(nhefs_weights, .weights = c(w_ate, w_att, w_atm)) #' #' # ESS by treatment group (binary exposure) -#' check_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk) +#' check_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk) #' #' # ESS by treatment group (categorical exposure) -#' check_ess(nhefs_weights, .weights = w_cat_ate, .group = alcoholfreq_cat) +#' check_ess(nhefs_weights, .weights = w_cat_ate, .exposure = alcoholfreq_cat) #' #' # ESS by quartiles of a continuous variable -#' check_ess(nhefs_weights, .weights = w_ate, .group = age, n_tiles = 4) +#' check_ess(nhefs_weights, .weights = w_ate, .exposure = age, n_tiles = 4) #' #' # Custom labels for continuous groups -#' check_ess(nhefs_weights, .weights = w_ate, .group = age, +#' check_ess(nhefs_weights, .weights = w_ate, .exposure = age, #' n_tiles = 3, tile_labels = c("Young", "Middle", "Older")) #' #' # Without unweighted comparison -#' check_ess(nhefs_weights, .weights = w_ate, .group = qsmk, +#' check_ess(nhefs_weights, .weights = w_ate, .exposure = qsmk, #' include_observed = FALSE) #' #' @export check_ess <- function( .data, .weights = NULL, - .group = NULL, + .exposure = NULL, include_observed = TRUE, n_tiles = 4, tile_labels = NULL @@ -72,13 +72,13 @@ check_ess <- function( # Validate inputs validate_data_frame(.data) - # Handle group variable - group_quo <- rlang::enquo(.group) + # Handle exposure variable + group_quo <- rlang::enquo(.exposure) has_group <- !rlang::quo_is_null(group_quo) if (has_group) { - group_name <- get_column_name(group_quo, ".group") - validate_column_exists(.data, group_name, ".group") + group_name <- get_column_name(group_quo, ".exposure") + validate_column_exists(.data, group_name, ".exposure") group_var <- .data[[group_name]] # Check if continuous (numeric and more than 10 unique values) diff --git a/R/geom_calibration.R b/R/geom_calibration.R index cadba8f..ef3ab55 100644 --- a/R/geom_calibration.R +++ b/R/geom_calibration.R @@ -8,7 +8,7 @@ #' @param data A data frame containing the data. #' @param .fitted Column name of predicted probabilities (numeric between 0 and 1). #' Can be unquoted (e.g., `p`) or quoted (e.g., `"p"`). -#' @param .group Column name of treatment/group variable. +#' @param .exposure Column name of treatment/exposure variable. #' Can be unquoted (e.g., `g`) or quoted (e.g., `"g"`). #' @inheritParams treatment_param #' @param method Character; calibration method. One of: "breaks", "logistic", or "windowed". @@ -50,7 +50,7 @@ check_model_calibration <- function( data, .fitted, - .group, + .exposure, .focal_level = NULL, method = c("breaks", "logistic", "windowed"), bins = 10, @@ -75,10 +75,10 @@ check_model_calibration <- function( } fitted_quo <- rlang::enquo(.fitted) - group_quo <- rlang::enquo(.group) + group_quo <- rlang::enquo(.exposure) fitted_name <- get_column_name(fitted_quo, ".fitted") - group_name <- get_column_name(group_quo, ".group") + group_name <- get_column_name(group_quo, ".exposure") group_var <- data[[group_name]] @@ -145,7 +145,7 @@ check_treatment_level <- function(group_var, .focal_level) { unique_levels <- unique(group_var[!is.na(group_var)]) if (length(unique_levels) > 0 && !.focal_level %in% unique_levels) { abort( - "{.code .focal_level} {.code {.focal_level}} not found in {.code .group} variable", + "{.code .focal_level} {.code {.focal_level}} not found in {.code .exposure} variable", error_class = "halfmoon_reference_error" ) } @@ -457,7 +457,7 @@ calculate_window_statistics <- function( StatCalibration <- ggplot2::ggproto( "StatCalibration", ggplot2::Stat, - required_aes = c("estimate", "truth"), + required_aes = c(".fitted", ".exposure"), default_aes = ggplot2::aes( x = ggplot2::after_stat(predicted_rate), y = ggplot2::after_stat(observed_rate), @@ -465,7 +465,7 @@ StatCalibration <- ggplot2::ggproto( ymax = ggplot2::after_stat(upper), alpha = 0.3 ), - dropped_aes = c("truth"), + dropped_aes = c(".exposure"), setup_params = function(data, params) { # Set default parameters params$method <- params$method %||% "breaks" @@ -500,7 +500,7 @@ StatCalibration <- ggplot2::ggproto( # We want to merge groups that differ only by truth factor levels aes_cols <- setdiff( names(data), - c("estimate", "truth", "weight", "PANEL", "group", "x", "y") + c(".fitted", ".exposure", "weight", "PANEL", "group", "x", "y") ) group_signatures <- purrr::map_chr( @@ -573,12 +573,12 @@ compute_calibration_for_group <- function( call = rlang::caller_env() ) { # Convert to binary using helper function - truth <- data$truth - treatment_indicator <- create_treatment_indicator(truth, .focal_level) + exposure <- data$.exposure + treatment_indicator <- create_treatment_indicator(exposure, .focal_level) # Create data frame for calibration computation df <- tibble::tibble( - x_var = data$estimate, + x_var = data$.fitted, y_var = treatment_indicator ) @@ -710,8 +710,8 @@ GeomCalibrationPoint <- ggplot2::ggproto( #' requiring additional packages #' } #' -#' @param mapping Aesthetic mapping (must supply `estimate` and `truth` if not inherited). -#' `estimate` should be propensity scores/predicted probabilities, `truth` should be treatment variable. +#' @param mapping Aesthetic mapping (must supply `.fitted` and `.exposure` if not inherited). +#' `.fitted` should be propensity scores/predicted probabilities, `.exposure` should be treatment variable. #' @param data Data frame or tibble; if NULL, uses ggplot default. #' @param method Character; calibration method - "breaks", "logistic", or "windowed". #' @param bins Integer >1; number of bins for the "breaks" method. @@ -733,25 +733,25 @@ GeomCalibrationPoint <- ggplot2::ggproto( #' #' # Basic calibration plot using nhefs_weights dataset #' # .fitted contains propensity scores, qsmk is the treatment variable -#' ggplot(nhefs_weights, aes(estimate = .fitted, truth = qsmk)) + +#' ggplot(nhefs_weights, aes(.fitted = .fitted, .exposure = qsmk)) + #' geom_calibration() + #' geom_abline(intercept = 0, slope = 1, linetype = "dashed") + #' labs(x = "Propensity Score", y = "Observed Treatment Rate") #' #' # Using different methods -#' ggplot(nhefs_weights, aes(estimate = .fitted, truth = qsmk)) + +#' ggplot(nhefs_weights, aes(.fitted = .fitted, .exposure = qsmk)) + #' geom_calibration(method = "logistic") + #' geom_abline(intercept = 0, slope = 1, linetype = "dashed") + #' labs(x = "Propensity Score", y = "Observed Treatment Rate") #' #' # Specify treatment level explicitly -#' ggplot(nhefs_weights, aes(estimate = .fitted, truth = qsmk)) + +#' ggplot(nhefs_weights, aes(.fitted = .fitted, .exposure = qsmk)) + #' geom_calibration(.focal_level = "1") + #' geom_abline(intercept = 0, slope = 1, linetype = "dashed") + #' labs(x = "Propensity Score", y = "Observed Treatment Rate") #' #' # Windowed method with custom parameters -#' ggplot(nhefs_weights, aes(estimate = .fitted, truth = qsmk)) + +#' ggplot(nhefs_weights, aes(.fitted = .fitted, .exposure = qsmk)) + #' geom_calibration(method = "windowed", window_size = 0.2, step_size = 0.1) + #' geom_abline(intercept = 0, slope = 1, linetype = "dashed") + #' labs(x = "Propensity Score", y = "Observed Treatment Rate") diff --git a/R/plot_calibration.R b/R/plot_calibration.R index 87f3909..f588997 100644 --- a/R/plot_calibration.R +++ b/R/plot_calibration.R @@ -70,9 +70,9 @@ plot_model_calibration <- function(x, ...) { #' @rdname plot_model_calibration #' @param .fitted Column name of predicted probabilities (propensity scores). #' Can be unquoted (e.g., `.fitted`) or quoted (e.g., `".fitted"`). -#' @param .group Column name of treatment/group variable. +#' @param .exposure Column name of treatment/exposure variable. #' Can be unquoted (e.g., `qsmk`) or quoted (e.g., `"qsmk"`). -#' @param .focal_level Value indicating which level of `.group` represents treatment. +#' @param .focal_level Value indicating which level of `.exposure` represents treatment. #' If NULL (default), uses the last level for factors or max value for numeric. #' @param method Character; calibration method - "breaks", "logistic", or "windowed". #' @param bins Integer >1; number of bins for the "breaks" method. @@ -89,7 +89,7 @@ plot_model_calibration <- function(x, ...) { plot_model_calibration.data.frame <- function( x, .fitted, - .group, + .exposure, .focal_level = NULL, method = "breaks", bins = 10, @@ -106,15 +106,15 @@ plot_model_calibration.data.frame <- function( ) { # Handle both quoted and unquoted column names using the same logic as check_calibration fitted_quo <- rlang::enquo(.fitted) - group_quo <- rlang::enquo(.group) + group_quo <- rlang::enquo(.exposure) fitted_name <- get_column_name(fitted_quo, ".fitted") - group_name <- get_column_name(group_quo, ".group") + group_name <- get_column_name(group_quo, ".exposure") # Create the base plot with new aesthetics p <- ggplot2::ggplot( x, - ggplot2::aes(estimate = .data[[fitted_name]], truth = .data[[group_name]]) + ggplot2::aes(.fitted = .data[[fitted_name]], .exposure = .data[[group_name]]) ) + geom_calibration( method = method, @@ -193,19 +193,19 @@ plot_model_calibration.glm <- function( .fitted <- stats::fitted(x) # For GLM/LM models, the response is the first column of the model frame - .group <- model_frame[[1]] + .exposure <- model_frame[[1]] # Create a data frame for plotting plot_data <- data.frame( .fitted = .fitted, - .group = .group + .exposure = .exposure ) # Call the data frame method plot_model_calibration.data.frame( plot_data, .fitted = .fitted, - .group = .group, + .exposure = .exposure, .focal_level = .focal_level, method = method, bins = bins, diff --git a/R/plot_ess.R b/R/plot_ess.R index 26f4e38..aefb34f 100644 --- a/R/plot_ess.R +++ b/R/plot_ess.R @@ -9,9 +9,9 @@ #' from the provided data. The plot shows how much "effective" sample size remains #' after weighting, which is a key diagnostic for assessing weight variability. #' -#' When `.group` is not provided, the function displays overall ESS for each -#' weighting method. When `.group` is provided, ESS is shown separately for each -#' group level using dodged bars. +#' When `.exposure` is not provided, the function displays overall ESS for each +#' weighting method. When `.exposure` is provided, ESS is shown separately for each +#' exposure level using dodged bars. #' #' For continuous grouping variables, the function automatically creates quantile #' groups (quartiles by default) to show how ESS varies across the distribution @@ -27,7 +27,7 @@ #' - Output from `check_ess()` containing ESS calculations #' - Raw data to compute ESS from (requires `.weights` to be specified) #' @inheritParams check_ess -#' @param fill_color Color for the bars when `.group` is not provided. +#' @param fill_color Color for the bars when `.exposure` is not provided. #' Default is "#0172B1". #' @param alpha Transparency level for the bars. Default is 0.8. #' @param show_labels Logical. Show ESS percentage values as text labels on bars? @@ -47,24 +47,24 @@ #' plot_ess(nhefs_weights, .weights = c(w_ate, w_att, w_atm)) #' #' # ESS by treatment group (binary exposure) -#' plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk) +#' plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk) #' #' # ESS by treatment group (categorical exposure) -#' plot_ess(nhefs_weights, .weights = w_cat_ate, .group = alcoholfreq_cat) +#' plot_ess(nhefs_weights, .weights = w_cat_ate, .exposure = alcoholfreq_cat) #' #' # ESS by age quartiles -#' plot_ess(nhefs_weights, .weights = w_ate, .group = age) +#' plot_ess(nhefs_weights, .weights = w_ate, .exposure = age) #' #' # Customize quantiles for continuous variable -#' plot_ess(nhefs_weights, .weights = w_ate, .group = age, +#' plot_ess(nhefs_weights, .weights = w_ate, .exposure = age, #' n_tiles = 5, tile_labels = c("Youngest", "Young", "Middle", "Older", "Oldest")) #' #' # Without percentage labels -#' plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk, +#' plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk, #' show_labels = FALSE) #' #' # Custom styling -#' plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk, +#' plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk, #' alpha = 0.6, fill_color = "steelblue", #' reference_line_color = "red") #' @@ -79,7 +79,7 @@ plot_ess <- function( .data, .weights = NULL, - .group = NULL, + .exposure = NULL, include_observed = TRUE, n_tiles = 4, tile_labels = NULL, @@ -99,7 +99,7 @@ plot_ess <- function( .data <- check_ess( .data = .data, .weights = {{ .weights }}, - .group = {{ .group }}, + .exposure = {{ .exposure }}, include_observed = include_observed, n_tiles = n_tiles, tile_labels = tile_labels diff --git a/R/plot_qq.R b/R/plot_qq.R index bb0b642..7b9116d 100644 --- a/R/plot_qq.R +++ b/R/plot_qq.R @@ -17,7 +17,7 @@ #' @param .data A data frame containing the variables or a halfmoon_qq object. #' @param ... Arguments passed to methods (see Methods section). #' @param .var Variable to plot. Can be unquoted (e.g., `age`) or quoted (e.g., `"age"`). -#' @param .group Column name of treatment/group variable. Can be unquoted (e.g., `qsmk`) or quoted (e.g., `"qsmk"`). +#' @param .exposure Column name of treatment/exposure variable. Can be unquoted (e.g., `qsmk`) or quoted (e.g., `"qsmk"`). #' @param .weights Optional weighting variable(s). Can be unquoted variable names, #' a character vector, or NULL. Multiple weights can be provided to compare #' different weighting schemes. Default is NULL (unweighted). @@ -70,7 +70,7 @@ plot_qq <- function(.data, ...) { plot_qq.default <- function( .data, .var, - .group, + .exposure, .weights = NULL, quantiles = seq(0.01, 0.99, 0.01), include_observed = TRUE, @@ -80,10 +80,10 @@ plot_qq.default <- function( ) { # Basic validation var_quo <- rlang::enquo(.var) - group_quo <- rlang::enquo(.group) + group_quo <- rlang::enquo(.exposure) var_name <- get_column_name(var_quo, ".var") - group_name <- get_column_name(group_quo, ".group") + group_name <- get_column_name(group_quo, ".exposure") if (!var_name %in% names(.data)) { abort( @@ -135,7 +135,7 @@ plot_qq.default <- function( # Validate .reference_level exists if (!.reference_level %in% group_levels) { abort( - "{.arg .reference_level} '{(.reference_level)}' not found in {.arg .group} levels: {.val {group_levels}}", + "{.arg .reference_level} '{(.reference_level)}' not found in {.arg .exposure} levels: {.val {group_levels}}", error_class = "halfmoon_reference_error" ) } @@ -185,7 +185,7 @@ plot_qq.default <- function( plot_data, ggplot2::aes( sample = {{ .var }}, - treatment = {{ .group }}, + treatment = {{ .exposure }}, weight = weight ) ) + @@ -199,7 +199,7 @@ plot_qq.default <- function( # No weights - just use geom_qq2 directly p <- ggplot2::ggplot( .data, - ggplot2::aes(sample = {{ .var }}, treatment = {{ .group }}) + ggplot2::aes(sample = {{ .var }}, treatment = {{ .exposure }}) ) + geom_qq2( quantiles = quantiles, diff --git a/R/utils.R b/R/utils.R index 7d64bed..89c6bce 100644 --- a/R/utils.R +++ b/R/utils.R @@ -92,7 +92,6 @@ utils::globalVariables(c( "method", "metric", "variable", - "estimate", ".bin", "bin", "n_events", @@ -104,6 +103,7 @@ utils::globalVariables(c( "fitted_mean", "group_mean", ".fitted", + ".exposure", ".group", "ymin", "ymax", diff --git a/man/check_ess.Rd b/man/check_ess.Rd index 30a1698..c4c0b78 100644 --- a/man/check_ess.Rd +++ b/man/check_ess.Rd @@ -7,7 +7,7 @@ check_ess( .data, .weights = NULL, - .group = NULL, + .exposure = NULL, include_observed = TRUE, n_tiles = 4, tile_labels = NULL @@ -20,23 +20,23 @@ check_ess( a character vector, or NULL. Multiple weights can be provided to compare different weighting schemes.} -\item{.group}{Optional grouping variable. When provided, ESS is calculated -separately for each group level. For continuous variables, groups are +\item{.exposure}{Optional exposure variable. When provided, ESS is calculated +separately for each exposure level. For continuous variables, groups are created using quantiles.} \item{include_observed}{Logical. If using \code{.weights}, also calculate observed (unweighted) metrics? Defaults to TRUE.} -\item{n_tiles}{For continuous \code{.group} variables, the number of quantile +\item{n_tiles}{For continuous \code{.exposure} variables, the number of quantile groups to create. Default is 4 (quartiles).} \item{tile_labels}{Optional character vector of labels for the quantile groups -when \code{.group} is continuous. If NULL, uses "Q1", "Q2", etc.} +when \code{.exposure} is continuous. If NULL, uses "Q1", "Q2", etc.} } \value{ A tibble with columns: \item{method}{Character. The weighting method ("observed" or weight variable name).} -\item{group}{Character. The group level (if \code{.group} is provided).} +\item{group}{Character. The exposure level (if \code{.exposure} is provided).} \item{n}{Integer. The number of observations in the group.} \item{ess}{Numeric. The effective sample size.} \item{ess_pct}{Numeric. ESS as a percentage of the actual sample size.} @@ -54,7 +54,7 @@ When weights vary substantially, the ESS can be much smaller than the actual number of observations, indicating that a few observations carry disproportionately large weights. -When \code{.group} is provided, ESS is calculated separately for each group level: +When \code{.exposure} is provided, ESS is calculated separately for each exposure level: \itemize{ \item For binary/categorical exposures: ESS is computed within each treatment level \item For continuous exposures: The variable is divided into quantiles (using @@ -69,20 +69,20 @@ further analysis. check_ess(nhefs_weights, .weights = c(w_ate, w_att, w_atm)) # ESS by treatment group (binary exposure) -check_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk) +check_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk) # ESS by treatment group (categorical exposure) -check_ess(nhefs_weights, .weights = w_cat_ate, .group = alcoholfreq_cat) +check_ess(nhefs_weights, .weights = w_cat_ate, .exposure = alcoholfreq_cat) # ESS by quartiles of a continuous variable -check_ess(nhefs_weights, .weights = w_ate, .group = age, n_tiles = 4) +check_ess(nhefs_weights, .weights = w_ate, .exposure = age, n_tiles = 4) # Custom labels for continuous groups -check_ess(nhefs_weights, .weights = w_ate, .group = age, +check_ess(nhefs_weights, .weights = w_ate, .exposure = age, n_tiles = 3, tile_labels = c("Young", "Middle", "Older")) # Without unweighted comparison -check_ess(nhefs_weights, .weights = w_ate, .group = qsmk, +check_ess(nhefs_weights, .weights = w_ate, .exposure = qsmk, include_observed = FALSE) } diff --git a/man/check_model_calibration.Rd b/man/check_model_calibration.Rd index bb1ef41..2f24ec2 100644 --- a/man/check_model_calibration.Rd +++ b/man/check_model_calibration.Rd @@ -7,7 +7,7 @@ check_model_calibration( data, .fitted, - .group, + .exposure, .focal_level = NULL, method = c("breaks", "logistic", "windowed"), bins = 10, @@ -26,7 +26,7 @@ check_model_calibration( \item{.fitted}{Column name of predicted probabilities (numeric between 0 and 1). Can be unquoted (e.g., \code{p}) or quoted (e.g., \code{"p"}).} -\item{.group}{Column name of treatment/group variable. +\item{.exposure}{Column name of treatment/exposure variable. Can be unquoted (e.g., \code{g}) or quoted (e.g., \code{"g"}).} \item{.focal_level}{The level of the outcome variable to consider as the diff --git a/man/geom_calibration.Rd b/man/geom_calibration.Rd index 30eddc8..c302e3b 100644 --- a/man/geom_calibration.Rd +++ b/man/geom_calibration.Rd @@ -26,8 +26,8 @@ geom_calibration( ) } \arguments{ -\item{mapping}{Aesthetic mapping (must supply \code{estimate} and \code{truth} if not inherited). -\code{estimate} should be propensity scores/predicted probabilities, \code{truth} should be treatment variable.} +\item{mapping}{Aesthetic mapping (must supply \code{.fitted} and \code{.exposure} if not inherited). +\code{.fitted} should be propensity scores/predicted probabilities, \code{.exposure} should be treatment variable.} \item{data}{Data frame or tibble; if NULL, uses ggplot default.} @@ -97,25 +97,25 @@ library(ggplot2) # Basic calibration plot using nhefs_weights dataset # .fitted contains propensity scores, qsmk is the treatment variable -ggplot(nhefs_weights, aes(estimate = .fitted, truth = qsmk)) + +ggplot(nhefs_weights, aes(.fitted = .fitted, .exposure = qsmk)) + geom_calibration() + geom_abline(intercept = 0, slope = 1, linetype = "dashed") + labs(x = "Propensity Score", y = "Observed Treatment Rate") # Using different methods -ggplot(nhefs_weights, aes(estimate = .fitted, truth = qsmk)) + +ggplot(nhefs_weights, aes(.fitted = .fitted, .exposure = qsmk)) + geom_calibration(method = "logistic") + geom_abline(intercept = 0, slope = 1, linetype = "dashed") + labs(x = "Propensity Score", y = "Observed Treatment Rate") # Specify treatment level explicitly -ggplot(nhefs_weights, aes(estimate = .fitted, truth = qsmk)) + +ggplot(nhefs_weights, aes(.fitted = .fitted, .exposure = qsmk)) + geom_calibration(.focal_level = "1") + geom_abline(intercept = 0, slope = 1, linetype = "dashed") + labs(x = "Propensity Score", y = "Observed Treatment Rate") # Windowed method with custom parameters -ggplot(nhefs_weights, aes(estimate = .fitted, truth = qsmk)) + +ggplot(nhefs_weights, aes(.fitted = .fitted, .exposure = qsmk)) + geom_calibration(method = "windowed", window_size = 0.2, step_size = 0.1) + geom_abline(intercept = 0, slope = 1, linetype = "dashed") + labs(x = "Propensity Score", y = "Observed Treatment Rate") diff --git a/man/plot_ess.Rd b/man/plot_ess.Rd index 8faf88a..852d5f4 100644 --- a/man/plot_ess.Rd +++ b/man/plot_ess.Rd @@ -7,7 +7,7 @@ plot_ess( .data, .weights = NULL, - .group = NULL, + .exposure = NULL, include_observed = TRUE, n_tiles = 4, tile_labels = NULL, @@ -31,20 +31,20 @@ plot_ess( a character vector, or NULL. Multiple weights can be provided to compare different weighting schemes.} -\item{.group}{Optional grouping variable. When provided, ESS is calculated -separately for each group level. For continuous variables, groups are +\item{.exposure}{Optional exposure variable. When provided, ESS is calculated +separately for each exposure level. For continuous variables, groups are created using quantiles.} \item{include_observed}{Logical. If using \code{.weights}, also calculate observed (unweighted) metrics? Defaults to TRUE.} -\item{n_tiles}{For continuous \code{.group} variables, the number of quantile +\item{n_tiles}{For continuous \code{.exposure} variables, the number of quantile groups to create. Default is 4 (quartiles).} \item{tile_labels}{Optional character vector of labels for the quantile groups -when \code{.group} is continuous. If NULL, uses "Q1", "Q2", etc.} +when \code{.exposure} is continuous. If NULL, uses "Q1", "Q2", etc.} -\item{fill_color}{Color for the bars when \code{.group} is not provided. +\item{fill_color}{Color for the bars when \code{.exposure} is not provided. Default is "#0172B1".} \item{alpha}{Transparency level for the bars. Default is 0.8.} @@ -74,9 +74,9 @@ This function visualizes the output of \code{check_ess()} or computes ESS direct from the provided data. The plot shows how much "effective" sample size remains after weighting, which is a key diagnostic for assessing weight variability. -When \code{.group} is not provided, the function displays overall ESS for each -weighting method. When \code{.group} is provided, ESS is shown separately for each -group level using dodged bars. +When \code{.exposure} is not provided, the function displays overall ESS for each +weighting method. When \code{.exposure} is provided, ESS is shown separately for each +exposure level using dodged bars. For continuous grouping variables, the function automatically creates quantile groups (quartiles by default) to show how ESS varies across the distribution @@ -95,24 +95,24 @@ Lower ESS percentages indicate: plot_ess(nhefs_weights, .weights = c(w_ate, w_att, w_atm)) # ESS by treatment group (binary exposure) -plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk) +plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk) # ESS by treatment group (categorical exposure) -plot_ess(nhefs_weights, .weights = w_cat_ate, .group = alcoholfreq_cat) +plot_ess(nhefs_weights, .weights = w_cat_ate, .exposure = alcoholfreq_cat) # ESS by age quartiles -plot_ess(nhefs_weights, .weights = w_ate, .group = age) +plot_ess(nhefs_weights, .weights = w_ate, .exposure = age) # Customize quantiles for continuous variable -plot_ess(nhefs_weights, .weights = w_ate, .group = age, +plot_ess(nhefs_weights, .weights = w_ate, .exposure = age, n_tiles = 5, tile_labels = c("Youngest", "Young", "Middle", "Older", "Oldest")) # Without percentage labels -plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk, +plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk, show_labels = FALSE) # Custom styling -plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk, +plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk, alpha = 0.6, fill_color = "steelblue", reference_line_color = "red") diff --git a/man/plot_model_calibration.Rd b/man/plot_model_calibration.Rd index d0516d3..2904acc 100644 --- a/man/plot_model_calibration.Rd +++ b/man/plot_model_calibration.Rd @@ -13,7 +13,7 @@ plot_model_calibration(x, ...) \method{plot_model_calibration}{data.frame}( x, .fitted, - .group, + .exposure, .focal_level = NULL, method = "breaks", bins = 10, @@ -79,10 +79,10 @@ plot_model_calibration(x, ...) \item{.fitted}{Column name of predicted probabilities (propensity scores). Can be unquoted (e.g., \code{.fitted}) or quoted (e.g., \code{".fitted"}).} -\item{.group}{Column name of treatment/group variable. +\item{.exposure}{Column name of treatment/exposure variable. Can be unquoted (e.g., \code{qsmk}) or quoted (e.g., \code{"qsmk"}).} -\item{.focal_level}{Value indicating which level of \code{.group} represents treatment. +\item{.focal_level}{Value indicating which level of \code{.exposure} represents treatment. If NULL (default), uses the last level for factors or max value for numeric.} \item{method}{Character; calibration method - "breaks", "logistic", or "windowed".} diff --git a/man/plot_qq.Rd b/man/plot_qq.Rd index abe0eb2..6d24bf2 100644 --- a/man/plot_qq.Rd +++ b/man/plot_qq.Rd @@ -11,7 +11,7 @@ plot_qq(.data, ...) \method{plot_qq}{default}( .data, .var, - .group, + .exposure, .weights = NULL, quantiles = seq(0.01, 0.99, 0.01), include_observed = TRUE, @@ -29,7 +29,7 @@ plot_qq(.data, ...) \item{.var}{Variable to plot. Can be unquoted (e.g., \code{age}) or quoted (e.g., \code{"age"}).} -\item{.group}{Column name of treatment/group variable. Can be unquoted (e.g., \code{qsmk}) or quoted (e.g., \code{"qsmk"}).} +\item{.exposure}{Column name of treatment/exposure variable. Can be unquoted (e.g., \code{qsmk}) or quoted (e.g., \code{"qsmk"}).} \item{.weights}{Optional weighting variable(s). Can be unquoted variable names, a character vector, or NULL. Multiple weights can be provided to compare diff --git a/tests/testthat/_snaps/check_ess.md b/tests/testthat/_snaps/check_ess.md index f1d9446..a3c454e 100644 --- a/tests/testthat/_snaps/check_ess.md +++ b/tests/testthat/_snaps/check_ess.md @@ -12,7 +12,7 @@ expr Condition Error in `check_ess()`: - ! Column `not_a_column` not found in `.group` + ! Column `not_a_column` not found in `.exposure` --- diff --git a/tests/testthat/_snaps/error-messages.md b/tests/testthat/_snaps/error-messages.md index d98ad66..f22fc3b 100644 --- a/tests/testthat/_snaps/error-messages.md +++ b/tests/testthat/_snaps/error-messages.md @@ -38,7 +38,7 @@ plot_qq(nhefs_weights, age, qsmk, .reference_level = "invalid") Condition Error in `plot_qq()`: - ! `.reference_level` 'invalid' not found in `.group` levels: "0" and "1" + ! `.reference_level` 'invalid' not found in `.exposure` levels: "0" and "1" --- diff --git a/tests/testthat/_snaps/plot_calibration/plot-calibration-glm-with-rug.svg b/tests/testthat/_snaps/plot_calibration/plot-calibration-glm-with-rug.svg index 3d421d9..e60c598 100644 --- a/tests/testthat/_snaps/plot_calibration/plot-calibration-glm-with-rug.svg +++ b/tests/testthat/_snaps/plot_calibration/plot-calibration-glm-with-rug.svg @@ -21,28 +21,28 @@ - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + 0.00 @@ -55,26 +55,26 @@ - - - - - -0.00 -0.25 -0.50 -0.75 -1.00 -predicted probability + + + + + +0.00 +0.25 +0.50 +0.75 +1.00 +predicted probability observed rate - -.group - - - - -0 -1 + +.exposure + + + + +0 +1 plot_calibration glm with rug diff --git a/tests/testthat/_snaps/plot_calibration/plot-calibration-lm-logistic-with-rug.svg b/tests/testthat/_snaps/plot_calibration/plot-calibration-lm-logistic-with-rug.svg index fc9eac7..1e707b2 100644 --- a/tests/testthat/_snaps/plot_calibration/plot-calibration-lm-logistic-with-rug.svg +++ b/tests/testthat/_snaps/plot_calibration/plot-calibration-lm-logistic-with-rug.svg @@ -21,18 +21,18 @@ - - + + - - - - - - - - + + + + + + + + 0.00 @@ -45,36 +45,36 @@ - - - - - -0.00 -0.25 -0.50 -0.75 -1.00 -predicted probability + + + + + +0.00 +0.25 +0.50 +0.75 +1.00 +predicted probability observed rate - -.group - - - - - - - - - - - -0.00 -0.25 -0.50 -0.75 -1.00 + +.exposure + + + + + + + + + + + +0.00 +0.25 +0.50 +0.75 +1.00 plot_calibration lm logistic with rug diff --git a/tests/testthat/_snaps/plot_qq.md b/tests/testthat/_snaps/plot_qq.md index a47eca8..39b49c1 100644 --- a/tests/testthat/_snaps/plot_qq.md +++ b/tests/testthat/_snaps/plot_qq.md @@ -12,7 +12,7 @@ expr Condition Error in `plot_qq()`: - ! Argument `.group` is required + ! Argument `.exposure` is required # plot_qq errors with missing columns diff --git a/tests/testthat/test-check_ess.R b/tests/testthat/test-check_ess.R index 215000c..f79f723 100644 --- a/tests/testthat/test-check_ess.R +++ b/tests/testthat/test-check_ess.R @@ -35,7 +35,7 @@ test_that("check_ess works without observed", { }) test_that("check_ess works with binary groups", { - result <- check_ess(nhefs_weights, .weights = w_ate, .group = qsmk) + result <- check_ess(nhefs_weights, .weights = w_ate, .exposure = qsmk) expect_s3_class(result, "tbl_df") expect_true("group" %in% names(result)) @@ -47,7 +47,7 @@ test_that("check_ess works with categorical groups", { result <- check_ess( nhefs_weights, .weights = w_cat_ate, - .group = alcoholfreq_cat + .exposure = alcoholfreq_cat ) expect_s3_class(result, "tbl_df") @@ -59,7 +59,7 @@ test_that("check_ess works with continuous groups", { result <- check_ess( nhefs_weights, .weights = w_ate, - .group = age, + .exposure = age, n_tiles = 4 ) @@ -74,7 +74,7 @@ test_that("check_ess works with custom tile labels", { result <- check_ess( nhefs_weights, .weights = w_ate, - .group = age, + .exposure = age, n_tiles = 3, tile_labels = labels ) @@ -109,7 +109,7 @@ test_that("check_ess validates inputs", { ) expect_halfmoon_error( - check_ess(nhefs_weights, .group = "not_a_column"), + check_ess(nhefs_weights, .exposure = "not_a_column"), "halfmoon_column_error" ) @@ -117,7 +117,7 @@ test_that("check_ess validates inputs", { check_ess( nhefs_weights, .weights = w_ate, - .group = age, + .exposure = age, n_tiles = 3, tile_labels = c("Too", "Few") ), diff --git a/tests/testthat/test-geom_calibration.R b/tests/testthat/test-geom_calibration.R index 69d6114..485a341 100644 --- a/tests/testthat/test-geom_calibration.R +++ b/tests/testthat/test-geom_calibration.R @@ -817,7 +817,7 @@ test_that("geom_calibration works with breaks method", { ) # Test breaks method - p_breaks <- ggplot(cal_data, aes(estimate = pred, truth = obs)) + + p_breaks <- ggplot(cal_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "breaks", bins = 5) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + labs(x = "Predicted Probability", y = "Observed Rate") + @@ -840,7 +840,7 @@ test_that("geom_calibration works with logistic method", { ) # Test logistic method (linear) - p_logistic <- ggplot(cal_data, aes(estimate = pred, truth = obs)) + + p_logistic <- ggplot(cal_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "logistic", smooth = FALSE, show_points = FALSE) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + labs(x = "Predicted Probability", y = "Observed Rate") + @@ -863,7 +863,7 @@ test_that("geom_calibration works with windowed method", { ) # Test windowed method - p_windowed <- ggplot(cal_data, aes(estimate = pred, truth = obs)) + + p_windowed <- ggplot(cal_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "windowed", window_size = 0.2, step_size = 0.1) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + labs(x = "Predicted Probability", y = "Observed Rate") + @@ -886,13 +886,13 @@ test_that("geom_calibration works with different show options", { ) # Test with ribbon hidden - p_no_ribbon <- ggplot(cal_data, aes(estimate = pred, truth = obs)) + + p_no_ribbon <- ggplot(cal_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "breaks", show_ribbon = FALSE) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + lims(x = c(0, 1), y = c(0, 1)) # Test with points hidden - p_no_points <- ggplot(cal_data, aes(estimate = pred, truth = obs)) + + p_no_points <- ggplot(cal_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "breaks", show_points = FALSE) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + lims(x = c(0, 1), y = c(0, 1)) @@ -916,7 +916,7 @@ test_that("geom_calibration handles different confidence levels", { ) # Test with 90% confidence level - p_90 <- ggplot(cal_data, aes(estimate = pred, truth = obs)) + + p_90 <- ggplot(cal_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "breaks", conf_level = 0.90) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + lims(x = c(0, 1), y = c(0, 1)) @@ -932,7 +932,7 @@ test_that("geom_calibration works with nhefs_weights data", { cal_data <- nhefs_weights cal_data$binary_outcome <- rbinom(nrow(cal_data), 1, cal_data$.fitted) - p_nhefs <- ggplot(cal_data, aes(estimate = .fitted, truth = binary_outcome)) + + p_nhefs <- ggplot(cal_data, aes(.fitted = .fitted, .exposure = binary_outcome)) + geom_calibration(method = "breaks", bins = 8) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + labs(x = "Propensity Score", y = "Observed Rate") + @@ -952,13 +952,13 @@ test_that("geom_calibration works with both numeric and factor outcomes", { test_data$obs_factor <- factor(test_data$obs_numeric, levels = c(0, 1)) # Test with numeric outcome - p_numeric <- ggplot(test_data, aes(estimate = pred, truth = obs_numeric)) + + p_numeric <- ggplot(test_data, aes(.fitted = pred, .exposure = obs_numeric)) + geom_calibration(method = "breaks", bins = 5) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + labs(title = "Calibration with numeric outcome") # Test with factor outcome - p_factor <- ggplot(test_data, aes(estimate = pred, truth = obs_factor)) + + p_factor <- ggplot(test_data, aes(.fitted = pred, .exposure = obs_factor)) + geom_calibration(method = "breaks", bins = 5) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + labs(title = "Calibration with factor outcome") @@ -988,7 +988,7 @@ test_that("geom_calibration errors with invalid method", { ) # Test with invalid method - error occurs during rendering - p <- ggplot(cal_data, aes(estimate = pred, truth = obs)) + + p <- ggplot(cal_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "invalid_method") # We expect a warning with the halfmoon_method_warning class @@ -1037,7 +1037,7 @@ test_that("geom_calibration logistic method works with smooth = TRUE", { ) # Test logistic method with smooth = TRUE (should work regardless of mgcv availability) - p_smooth <- ggplot(cal_data, aes(estimate = pred, truth = obs)) + + p_smooth <- ggplot(cal_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "logistic", smooth = TRUE, show_points = FALSE) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + labs(x = "Predicted Probability", y = "Observed Rate") + @@ -1214,19 +1214,19 @@ test_that("k parameter works in geom_calibration", { ) # Create plots with different k values - p_k5 <- ggplot(test_data, aes(estimate = pred, truth = obs)) + + p_k5 <- ggplot(test_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "logistic", smooth = TRUE, k = 5) + geom_abline(intercept = 0, slope = 1, linetype = "dashed") + labs(x = "Predicted Probability", y = "Observed Rate") + lims(x = c(0, 1), y = c(0, 1)) - p_k10 <- ggplot(test_data, aes(estimate = pred, truth = obs)) + + p_k10 <- ggplot(test_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "logistic", smooth = TRUE, k = 10) + geom_abline(intercept = 0, slope = 1, linetype = "dashed") + labs(x = "Predicted Probability", y = "Observed Rate") + lims(x = c(0, 1), y = c(0, 1)) - p_k20 <- ggplot(test_data, aes(estimate = pred, truth = obs)) + + p_k20 <- ggplot(test_data, aes(.fitted = pred, .exposure = obs)) + geom_calibration(method = "logistic", smooth = TRUE, k = 20) + geom_abline(intercept = 0, slope = 1, linetype = "dashed") + labs(x = "Predicted Probability", y = "Observed Rate") + diff --git a/tests/testthat/test-plot_ess.R b/tests/testthat/test-plot_ess.R index af98ee2..397320c 100644 --- a/tests/testthat/test-plot_ess.R +++ b/tests/testthat/test-plot_ess.R @@ -32,7 +32,7 @@ test_that("plot_ess works without groups", { }) test_that("plot_ess works with groups", { - p <- plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk) + p <- plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk) # Should have fill aesthetic for groups expect_true("fill" %in% names(p$mapping)) @@ -88,7 +88,7 @@ test_that("plot_ess y-axis uses percent scale", { }) test_that("plot_ess handles continuous groups", { - p <- plot_ess(nhefs_weights, .weights = w_ate, .group = age, n_tiles = 4) + p <- plot_ess(nhefs_weights, .weights = w_ate, .exposure = age, n_tiles = 4) expect_s3_class(p, "ggplot") expect_true("fill" %in% names(p$mapping)) @@ -154,7 +154,7 @@ test_that("plot_ess snapshot tests", { # Plot with groups expect_doppelganger( "plot_ess_groups", - plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .group = qsmk) + plot_ess(nhefs_weights, .weights = c(w_ate, w_att), .exposure = qsmk) ) # Plot without labels @@ -166,6 +166,6 @@ test_that("plot_ess snapshot tests", { # Plot with continuous groups expect_doppelganger( "plot_ess_continuous", - plot_ess(nhefs_weights, .weights = w_ate, .group = age, n_tiles = 3) + plot_ess(nhefs_weights, .weights = w_ate, .exposure = age, n_tiles = 3) ) }) From f922d513a85f2ed6384ec2e30ba5c97158df6b74 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Sun, 24 Aug 2025 11:07:32 -0400 Subject: [PATCH 02/14] .estimate -> .fitted --- R/bal_model_auc.R | 8 ++++---- R/bal_model_roc_curve.R | 8 ++++---- R/check_model_auc.R | 16 ++++++++-------- R/plot_calibration.R | 5 ++++- R/utils.R | 1 + README.Rmd | 4 ++-- README.md | 4 ++-- man/bal_model_auc.Rd | 4 ++-- man/bal_model_roc_curve.Rd | 4 ++-- man/check_model_auc.Rd | 4 ++-- man/check_model_roc_curve.Rd | 4 ++-- tests/testthat/_snaps/check_model_auc.md | 2 +- tests/testthat/test-geom_calibration.R | 5 ++++- 13 files changed, 38 insertions(+), 31 deletions(-) diff --git a/R/bal_model_auc.R b/R/bal_model_auc.R index 6ea4c39..b39ba3c 100644 --- a/R/bal_model_auc.R +++ b/R/bal_model_auc.R @@ -16,7 +16,7 @@ #' #' @param .data A data frame containing the variables. #' @param .exposure The treatment/outcome variable (unquoted). -#' @param .estimate The propensity score or fitted values (unquoted). +#' @param .fitted The propensity score or fitted values (unquoted). #' @param .weights Optional single weight variable (unquoted). If NULL, computes #' unweighted AUC. #' @inheritParams balance_params @@ -40,7 +40,7 @@ bal_model_auc <- function( .data, .exposure, - .estimate, + .fitted, .weights = NULL, na.rm = TRUE, .focal_level = NULL @@ -48,7 +48,7 @@ bal_model_auc <- function( validate_data_frame(.data, call = rlang::caller_env()) exposure_quo <- rlang::enquo(.exposure) - estimate_quo <- rlang::enquo(.estimate) + estimate_quo <- rlang::enquo(.fitted) wts_quo <- rlang::enquo(.weights) # Extract column names @@ -64,7 +64,7 @@ bal_model_auc <- function( } if (length(estimate_name) != 1) { abort( - "{.arg .estimate} must select exactly one variable", + "{.arg .fitted} must select exactly one variable", error_class = "halfmoon_arg_error", call = rlang::current_env() ) diff --git a/R/bal_model_roc_curve.R b/R/bal_model_roc_curve.R index a69e5fd..bdfc646 100644 --- a/R/bal_model_roc_curve.R +++ b/R/bal_model_roc_curve.R @@ -17,7 +17,7 @@ #' #' @param .data A data frame containing the variables. #' @param .exposure The treatment/outcome variable (unquoted). -#' @param .estimate The propensity score or fitted values (unquoted). +#' @param .fitted The propensity score or fitted values (unquoted). #' @param .weights Optional single weight variable (unquoted). If NULL, computes #' unweighted ROC curve. #' @inheritParams balance_params @@ -43,7 +43,7 @@ bal_model_roc_curve <- function( .data, .exposure, - .estimate, + .fitted, .weights = NULL, na.rm = TRUE, .focal_level = NULL @@ -51,7 +51,7 @@ bal_model_roc_curve <- function( validate_data_frame(.data, call = rlang::caller_env()) exposure_quo <- rlang::enquo(.exposure) - estimate_quo <- rlang::enquo(.estimate) + estimate_quo <- rlang::enquo(.fitted) wts_quo <- rlang::enquo(.weights) # Extract column names @@ -67,7 +67,7 @@ bal_model_roc_curve <- function( } if (length(estimate_name) != 1) { abort( - "{.arg .estimate} must select exactly one variable", + "{.arg .fitted} must select exactly one variable", error_class = "halfmoon_arg_error", call = rlang::current_env() ) diff --git a/R/check_model_auc.R b/R/check_model_auc.R index d89b7b4..e3a8266 100644 --- a/R/check_model_auc.R +++ b/R/check_model_auc.R @@ -20,7 +20,7 @@ #' #' @param .data A data frame containing the variables. #' @param .exposure The treatment/outcome variable. -#' @param .estimate The propensity score or fitted values. +#' @param .fitted The propensity score or fitted values. #' @param .weights Weighting variables (supports tidyselect). #' @inheritParams check_params #' @inheritParams balance_params @@ -44,7 +44,7 @@ check_model_auc <- function( .data, .exposure, - .estimate, + .fitted, .weights, include_observed = TRUE, na.rm = TRUE, @@ -55,7 +55,7 @@ check_model_auc <- function( roc_data <- check_model_roc_curve( .data, {{ .exposure }}, - {{ .estimate }}, + {{ .fitted }}, {{ .weights }}, include_observed, na.rm, @@ -100,7 +100,7 @@ compute_method_auc <- function(method, roc_data) { #' #' @param .data A data frame containing the variables. #' @param .exposure The treatment/outcome variable (unquoted). -#' @param .estimate The propensity score or covariate (unquoted). +#' @param .fitted The propensity score or covariate (unquoted). #' @param .weights Optional weighting variables (unquoted, can be multiple). #' @param include_observed Include unweighted results? Default TRUE. #' @param na.rm Remove missing values? Default TRUE. @@ -114,14 +114,14 @@ compute_method_auc <- function(method, roc_data) { check_model_roc_curve <- function( .data, .exposure, - .estimate, + .fitted, .weights = NULL, include_observed = TRUE, na.rm = TRUE, .focal_level = NULL ) { truth_quo <- rlang::enquo(.exposure) - estimate_quo <- rlang::enquo(.estimate) + estimate_quo <- rlang::enquo(.fitted) wts_quo <- rlang::enquo(.weights) validate_data_frame(.data) @@ -139,7 +139,7 @@ check_model_roc_curve <- function( } if (length(estimate_name) != 1) { abort( - "{.arg .estimate} must select exactly one variable", + "{.arg .fitted} must select exactly one variable", error_class = "halfmoon_select_error", call = rlang::current_env() ) @@ -186,7 +186,7 @@ check_model_roc_curve <- function( ) } - validate_numeric(estimate, ".estimate") + validate_numeric(estimate, ".fitted") if (na.rm) { complete_cases <- stats::complete.cases(truth, estimate) diff --git a/R/plot_calibration.R b/R/plot_calibration.R index f588997..8761aac 100644 --- a/R/plot_calibration.R +++ b/R/plot_calibration.R @@ -114,7 +114,10 @@ plot_model_calibration.data.frame <- function( # Create the base plot with new aesthetics p <- ggplot2::ggplot( x, - ggplot2::aes(.fitted = .data[[fitted_name]], .exposure = .data[[group_name]]) + ggplot2::aes( + .fitted = .data[[fitted_name]], + .exposure = .data[[group_name]] + ) ) + geom_calibration( method = method, diff --git a/R/utils.R b/R/utils.R index 89c6bce..fb3f4ed 100644 --- a/R/utils.R +++ b/R/utils.R @@ -105,6 +105,7 @@ utils::globalVariables(c( ".fitted", ".exposure", ".group", + "estimate", "ymin", "ymax", "x_quantiles", diff --git a/README.Rmd b/README.Rmd index dddc90f..6c7ffcb 100644 --- a/README.Rmd +++ b/README.Rmd @@ -111,14 +111,14 @@ Assess how well your propensity score model discriminates between treatment grou roc_results <- check_model_roc_curve( nhefs_weights, .exposure = qsmk, - .estimate = .fitted, + .fitted = .fitted, .weights = c(w_ate, w_att, w_atm, w_ato) ) auc_results <- check_model_auc( nhefs_weights, .exposure = qsmk, - .estimate = .fitted, + .fitted = .fitted, .weights = c(w_ate, w_att, w_atm, w_ato) ) diff --git a/README.md b/README.md index 0fbab59..d935480 100644 --- a/README.md +++ b/README.md @@ -122,14 +122,14 @@ about 0.5 (what you would observe from a randomized experiment): roc_results <- check_model_roc_curve( nhefs_weights, .exposure = qsmk, - .estimate = .fitted, + .fitted = .fitted, .weights = c(w_ate, w_att, w_atm, w_ato) ) auc_results <- check_model_auc( nhefs_weights, .exposure = qsmk, - .estimate = .fitted, + .fitted = .fitted, .weights = c(w_ate, w_att, w_atm, w_ato) ) diff --git a/man/bal_model_auc.Rd b/man/bal_model_auc.Rd index a3ca113..deb28c0 100644 --- a/man/bal_model_auc.Rd +++ b/man/bal_model_auc.Rd @@ -7,7 +7,7 @@ bal_model_auc( .data, .exposure, - .estimate, + .fitted, .weights = NULL, na.rm = TRUE, .focal_level = NULL @@ -18,7 +18,7 @@ bal_model_auc( \item{.exposure}{The treatment/outcome variable (unquoted).} -\item{.estimate}{The propensity score or fitted values (unquoted).} +\item{.fitted}{The propensity score or fitted values (unquoted).} \item{.weights}{Optional single weight variable (unquoted). If NULL, computes unweighted AUC.} diff --git a/man/bal_model_roc_curve.Rd b/man/bal_model_roc_curve.Rd index d3e147d..a58cb2e 100644 --- a/man/bal_model_roc_curve.Rd +++ b/man/bal_model_roc_curve.Rd @@ -7,7 +7,7 @@ bal_model_roc_curve( .data, .exposure, - .estimate, + .fitted, .weights = NULL, na.rm = TRUE, .focal_level = NULL @@ -18,7 +18,7 @@ bal_model_roc_curve( \item{.exposure}{The treatment/outcome variable (unquoted).} -\item{.estimate}{The propensity score or fitted values (unquoted).} +\item{.fitted}{The propensity score or fitted values (unquoted).} \item{.weights}{Optional single weight variable (unquoted). If NULL, computes unweighted ROC curve.} diff --git a/man/check_model_auc.Rd b/man/check_model_auc.Rd index 531cfe9..27af5b1 100644 --- a/man/check_model_auc.Rd +++ b/man/check_model_auc.Rd @@ -7,7 +7,7 @@ check_model_auc( .data, .exposure, - .estimate, + .fitted, .weights, include_observed = TRUE, na.rm = TRUE, @@ -19,7 +19,7 @@ check_model_auc( \item{.exposure}{The treatment/outcome variable.} -\item{.estimate}{The propensity score or fitted values.} +\item{.fitted}{The propensity score or fitted values.} \item{.weights}{Weighting variables (supports tidyselect).} diff --git a/man/check_model_roc_curve.Rd b/man/check_model_roc_curve.Rd index 2c2fe77..d963de1 100644 --- a/man/check_model_roc_curve.Rd +++ b/man/check_model_roc_curve.Rd @@ -7,7 +7,7 @@ check_model_roc_curve( .data, .exposure, - .estimate, + .fitted, .weights = NULL, include_observed = TRUE, na.rm = TRUE, @@ -19,7 +19,7 @@ check_model_roc_curve( \item{.exposure}{The treatment/outcome variable (unquoted).} -\item{.estimate}{The propensity score or covariate (unquoted).} +\item{.fitted}{The propensity score or covariate (unquoted).} \item{.weights}{Optional weighting variables (unquoted, can be multiple).} diff --git a/tests/testthat/_snaps/check_model_auc.md b/tests/testthat/_snaps/check_model_auc.md index 0cc2dab..0e2419e 100644 --- a/tests/testthat/_snaps/check_model_auc.md +++ b/tests/testthat/_snaps/check_model_auc.md @@ -28,7 +28,7 @@ expr Condition Error in `check_model_roc_curve()`: - ! `.estimate` must be numeric, got + ! `.fitted` must be numeric, got --- diff --git a/tests/testthat/test-geom_calibration.R b/tests/testthat/test-geom_calibration.R index 485a341..b353d93 100644 --- a/tests/testthat/test-geom_calibration.R +++ b/tests/testthat/test-geom_calibration.R @@ -932,7 +932,10 @@ test_that("geom_calibration works with nhefs_weights data", { cal_data <- nhefs_weights cal_data$binary_outcome <- rbinom(nrow(cal_data), 1, cal_data$.fitted) - p_nhefs <- ggplot(cal_data, aes(.fitted = .fitted, .exposure = binary_outcome)) + + p_nhefs <- ggplot( + cal_data, + aes(.fitted = .fitted, .exposure = binary_outcome) + ) + geom_calibration(method = "breaks", bins = 8) + geom_abline(slope = 1, intercept = 0, linetype = "dashed") + labs(x = "Propensity Score", y = "Observed Rate") + From 729d8f0d88f46bf93b8ed20addd998f09003427c Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Mon, 25 Aug 2025 15:43:41 -0400 Subject: [PATCH 03/14] add examples --- R/check_model_auc.R | 26 ++++++++++++++++++++++++++ man/check_model_roc_curve.Rd | 27 +++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/R/check_model_auc.R b/R/check_model_auc.R index e3a8266..8473dcd 100644 --- a/R/check_model_auc.R +++ b/R/check_model_auc.R @@ -110,6 +110,32 @@ compute_method_auc <- function(method, roc_data) { #' @return A tibble with class "halfmoon_roc" containing ROC curve data. #' @family balance functions #' @seealso [check_model_auc()] for AUC summaries, [bal_model_roc_curve()] for single ROC curves +#' @examples +#' # Check ROC curves for propensity scores with multiple weights +#' roc_data <- check_model_roc_curve( +#' nhefs_weights, +#' qsmk, +#' .fitted, +#' c(w_ate, w_att) +#' ) +#' +#' # Check ROC curve for a single weight without observed +#' check_model_roc_curve( +#' nhefs_weights, +#' qsmk, +#' .fitted, +#' w_ate, +#' include_observed = FALSE +#' ) +#' +#' # Specify a different focal level +#' check_model_roc_curve( +#' nhefs_weights, +#' qsmk, +#' .fitted, +#' w_ate, +#' .focal_level = 0 # Use 0 as the treatment level instead of 1 +#' ) #' @export check_model_roc_curve <- function( .data, diff --git a/man/check_model_roc_curve.Rd b/man/check_model_roc_curve.Rd index d963de1..5aaf24e 100644 --- a/man/check_model_roc_curve.Rd +++ b/man/check_model_roc_curve.Rd @@ -38,6 +38,33 @@ Computes ROC curves (weighted or unweighted) for evaluating propensity score bal In causal inference, an ROC curve near the diagonal (AUC around 0.5) indicates good balance between treatment groups. } +\examples{ +# Check ROC curves for propensity scores with multiple weights +roc_data <- check_model_roc_curve( + nhefs_weights, + qsmk, + .fitted, + c(w_ate, w_att) +) + +# Check ROC curve for a single weight without observed +check_model_roc_curve( + nhefs_weights, + qsmk, + .fitted, + w_ate, + include_observed = FALSE +) + +# Specify a different focal level +check_model_roc_curve( + nhefs_weights, + qsmk, + .fitted, + w_ate, + .focal_level = 0 # Use 0 as the treatment level instead of 1 +) +} \seealso{ \code{\link[=check_model_auc]{check_model_auc()}} for AUC summaries, \code{\link[=bal_model_roc_curve]{bal_model_roc_curve()}} for single ROC curves From 2632e265680a5d7fd19190c5330c0f2cd6e7aba1 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Mon, 25 Aug 2025 16:32:02 -0400 Subject: [PATCH 04/14] fix missed names --- R/geom_calibration.R | 4 ++-- R/utils-group.R | 12 ++++++------ tests/testthat/_snaps/check_model_auc.md | 2 +- tests/testthat/test-bal_qq.R | 4 ++-- tests/testthat/test-check_model_auc.R | 6 +++--- tests/testthat/test-geom_calibration.R | 8 ++++---- tests/testthat/test-plot_calibration.R | 14 +++++++------- tests/testthat/test-plot_qq.R | 2 +- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/R/geom_calibration.R b/R/geom_calibration.R index ef3ab55..4ed0274 100644 --- a/R/geom_calibration.R +++ b/R/geom_calibration.R @@ -84,7 +84,7 @@ check_model_calibration <- function( check_columns(data, fitted_name, group_name, .focal_level) - treatment_indicator <- check_treatment_level(group_var, .focal_level) + treatment_indicator <- check_focal_level(group_var, .focal_level) df <- tibble::tibble( x_var = data[[fitted_name]], @@ -139,7 +139,7 @@ empty_calibration <- function(method = "breaks") { } } -check_treatment_level <- function(group_var, .focal_level) { +check_focal_level <- function(group_var, .focal_level) { # Validate treatment level exists if provided if (!is.null(.focal_level)) { unique_levels <- unique(group_var[!is.na(group_var)]) diff --git a/R/utils-group.R b/R/utils-group.R index 3654883..33b28f8 100644 --- a/R/utils-group.R +++ b/R/utils-group.R @@ -65,7 +65,7 @@ determine_reference_group <- function( } # Create treatment indicator -create_treatment_indicator <- function(group, treatment_level = NULL) { +create_treatment_indicator <- function(group, .focal_level = NULL) { unique_levels <- unique(group[!is.na(group)]) # Handle empty groups @@ -73,19 +73,19 @@ create_treatment_indicator <- function(group, treatment_level = NULL) { return(integer(length(group))) } - if (is.null(treatment_level)) { + if (is.null(.focal_level)) { if (is.factor(group)) { - treatment_level <- levels(group)[length(levels(group))] + .focal_level <- levels(group)[length(levels(group))] } else { - treatment_level <- max(unique_levels, na.rm = TRUE) + .focal_level <- max(unique_levels, na.rm = TRUE) } } # Handle both factor and non-factor variables if (is.factor(group)) { - as.integer(as.character(group) == as.character(treatment_level)) + as.integer(as.character(group) == as.character(.focal_level)) } else { - as.integer(group == treatment_level) + as.integer(group == .focal_level) } } diff --git a/tests/testthat/_snaps/check_model_auc.md b/tests/testthat/_snaps/check_model_auc.md index 0e2419e..9e40425 100644 --- a/tests/testthat/_snaps/check_model_auc.md +++ b/tests/testthat/_snaps/check_model_auc.md @@ -38,7 +38,7 @@ Error in `check_model_roc_curve()`: ! `.exposure` must have exactly 2 levels -# treatment_level parameter works correctly +# .focal_level parameter works correctly Code expr diff --git a/tests/testthat/test-bal_qq.R b/tests/testthat/test-bal_qq.R index 6d083fa..614282a 100644 --- a/tests/testthat/test-bal_qq.R +++ b/tests/testthat/test-bal_qq.R @@ -96,7 +96,7 @@ test_that("bal_qq works with different treatment levels", { quantiles = c(0.25, 0.5, 0.75) ) - # Default should match explicit treatment_level = 1 + # Default should match explicit .focal_level = 1 expect_equal(qq_default$exposed_quantiles, qq_1$exposed_quantiles) expect_equal(qq_default$unexposed_quantiles, qq_1$unexposed_quantiles) @@ -121,7 +121,7 @@ test_that("bal_qq works with different treatment levels", { }) test_that("bal_qq matches single method from check_qq", { - # Test with default treatment_level (should use last/max level) + # Test with default .focal_level (should use last/max level) qq_single <- bal_qq(nhefs_weights, age, qsmk, quantiles = seq(0.1, 0.9, 0.1)) qq_check <- check_qq( nhefs_weights, diff --git a/tests/testthat/test-check_model_auc.R b/tests/testthat/test-check_model_auc.R index 62049dc..a7a92d8 100644 --- a/tests/testthat/test-check_model_auc.R +++ b/tests/testthat/test-check_model_auc.R @@ -307,7 +307,7 @@ test_that("weighted ROC/AUC integrates with check_balance patterns", { expect_true(all(c("method", "auc") %in% colnames(balance_roc))) }) -test_that("treatment_level parameter works correctly", { +test_that(".focal_level parameter works correctly", { # Test with default (second level) roc_default <- check_model_roc_curve( nhefs_weights, @@ -328,7 +328,7 @@ test_that("treatment_level parameter works correctly", { # Should be identical expect_equal(roc_default, roc_explicit) - # Test with treatment_level = "0" (opposite) + # Test with .focal_level = "0" (opposite) roc_opposite <- check_model_roc_curve( nhefs_weights, qsmk, @@ -340,7 +340,7 @@ test_that("treatment_level parameter works correctly", { # ROC curves should be different expect_false(identical(roc_default, roc_opposite)) - # Test with invalid treatment_level + # Test with invalid .focal_level expect_halfmoon_error( check_model_roc_curve( nhefs_weights, diff --git a/tests/testthat/test-geom_calibration.R b/tests/testthat/test-geom_calibration.R index b353d93..cb42260 100644 --- a/tests/testthat/test-geom_calibration.R +++ b/tests/testthat/test-geom_calibration.R @@ -468,14 +468,14 @@ test_that("check_model_calibration handles edge cases with all methods", { test_that("check_model_calibration handles all zeros and all ones", { set.seed(123) - # All zeros - when treatment_level is not specified, 0 becomes the treatment level + # All zeros - when .focal_level is not specified, 0 becomes the treatment level # so observed_rate will be 1 (all observations match treatment level) zeros_data <- data.frame( pred = runif(50, 0, 1), obs = rep(0, 50) ) - # When all observations are 0, default treatment_level will be 0 + # When all observations are 0, default .focal_level will be 0 # Test the actual behavior result_breaks_zeros_default <- suppress_calibration_warnings(check_model_calibration( zeros_data, @@ -483,7 +483,7 @@ test_that("check_model_calibration handles all zeros and all ones", { obs, method = "breaks" )) - # All values are 0 and treatment_level=0, so observed_rate=1 + # All values are 0 and .focal_level=0, so observed_rate=1 expect_true(all(result_breaks_zeros_default$observed_rate == 1)) # Now test with mixed data where 1 is the treatment level @@ -533,7 +533,7 @@ test_that("check_model_calibration handles all zeros and all ones", { obs, method = "breaks" )) - # With default treatment_level, all zeros means treatment_level=0, so observed_rate=1 + # With default .focal_level, all zeros means .focal_level=0, so observed_rate=1 expect_true(all(result_default_zeros$observed_rate == 1)) }) diff --git a/tests/testthat/test-plot_calibration.R b/tests/testthat/test-plot_calibration.R index a16c111..55b7bd1 100644 --- a/tests/testthat/test-plot_calibration.R +++ b/tests/testthat/test-plot_calibration.R @@ -48,13 +48,13 @@ test_that("plot_model_calibration works with different methods", { expect_s3_class(p_windowed, "ggplot") }) -test_that("plot_model_calibration works with treatment level specification", { - # Test with explicit treatment level +test_that("plot_model_calibration works with focal level specification", { + # Test with explicit focal level p <- plot_model_calibration( nhefs_weights, .fitted, qsmk, - treatment_level = "1" + .focal_level = "1" ) expect_s3_class(p, "ggplot") @@ -205,8 +205,8 @@ test_that("plot_model_calibration works with glm objects", { p_rug <- plot_model_calibration(ps_model, include_rug = TRUE) expect_s3_class(p_rug, "ggplot") - # Test with treatment level - p_treatment <- plot_model_calibration(ps_model, treatment_level = 1) + # Test with focal level + p_treatment <- plot_model_calibration(ps_model, .focal_level = 1) expect_s3_class(p_treatment, "ggplot") }) @@ -280,12 +280,12 @@ test_that("plot_model_calibration visual snapshot tests", { ) expect_doppelganger("plot_calibration windowed", p4) - # With explicit treatment level + # With explicit focal level p5 <- plot_model_calibration( nhefs_weights, .fitted, qsmk, - treatment_level = "1" + .focal_level = "1" ) expect_doppelganger("plot_calibration explicit treatment", p5) diff --git a/tests/testthat/test-plot_qq.R b/tests/testthat/test-plot_qq.R index 7523dd7..bcdd897 100644 --- a/tests/testthat/test-plot_qq.R +++ b/tests/testthat/test-plot_qq.R @@ -3,7 +3,7 @@ test_that("plot_qq creates basic QQ plot", { expect_s3_class(p, "ggplot") expect_equal(length(p$layers), 2) # points + abline - # With NULL treatment_level, uses last level (1) as reference + # With NULL .focal_level, uses last level (1) as reference expect_equal(p$labels$x, "age (qsmk = 1)") expect_equal(p$labels$y, "age (qsmk = 0)") }) From 76a5c63280d241cf27692061093c373e822bbb58 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Thu, 4 Sep 2025 11:39:24 -0400 Subject: [PATCH 05/14] allow flexible facet scales --- R/plot_mirror_distributions.R | 17 +- man/plot_mirror_distributions.Rd | 8 +- .../categorical-custom-reference.svg | 351 +++++----- .../categorical-exposure-density.svg | 330 +++++---- .../categorical-exposure-histogram.svg | 648 ++++++++--------- .../categorical-fixed-scales.svg | 255 +++++++ .../categorical-free-y-scales.svg | 271 ++++++++ .../categorical-multiple-weights.svg | 264 +++---- .../categorical-no-unweighted.svg | 165 ++--- .../categorical-with-weights.svg | 652 ++++++++---------- .../fixed-facet-scales-default.svg | 218 ++++++ .../free-facet-scales.svg | 325 +++++++++ .../free-y-facet-scales.svg | 230 ++++++ .../multiple-weights.svg | 492 +++++++------ .../weighted-density.svg | 204 +++--- .../weighted-histogram-default.svg | 332 +++++---- .../testthat/test-plot_mirror_distributions.R | 59 ++ 17 files changed, 3007 insertions(+), 1814 deletions(-) create mode 100644 tests/testthat/_snaps/plot_mirror_distributions/categorical-fixed-scales.svg create mode 100644 tests/testthat/_snaps/plot_mirror_distributions/categorical-free-y-scales.svg create mode 100644 tests/testthat/_snaps/plot_mirror_distributions/fixed-facet-scales-default.svg create mode 100644 tests/testthat/_snaps/plot_mirror_distributions/free-facet-scales.svg create mode 100644 tests/testthat/_snaps/plot_mirror_distributions/free-y-facet-scales.svg diff --git a/R/plot_mirror_distributions.R b/R/plot_mirror_distributions.R index a14a819..c17032a 100644 --- a/R/plot_mirror_distributions.R +++ b/R/plot_mirror_distributions.R @@ -44,6 +44,10 @@ #' @param .reference_level The reference group level for categorical exposures (>2 levels). #' Can be a string (group level) or numeric (position). Defaults to 1 (first level). #' Only used when .exposure has more than 2 levels. +#' @param facet_scales Character. Scale specification for facets. Defaults to +#' "fixed" to match ggplot2's default behavior. Options are +#' "fixed", "free_x", "free_y", or "free". Use "free_y" to allow different +#' y-axis scales across panels, which was the previous default behavior. #' #' @return A ggplot2 object. #' @@ -115,7 +119,8 @@ plot_mirror_distributions <- function( include_unweighted = TRUE, alpha = 0.6, na.rm = FALSE, - .reference_level = 1L + .reference_level = 1L, + facet_scales = "fixed" ) { type <- match.arg(type) @@ -220,9 +225,9 @@ plot_mirror_distributions <- function( na.rm = na.rm ) + if (is_categorical) { - ggplot2::facet_grid(comparison ~ method, scales = "free_y") + ggplot2::facet_grid(comparison ~ method, scales = facet_scales) } else { - ggplot2::facet_wrap(~method, scales = "free_y") + ggplot2::facet_wrap(~method, scales = facet_scales) } } else { p <- ggplot2::ggplot(plot_data, ggplot2::aes(x = .data[[var_name]])) + @@ -238,9 +243,9 @@ plot_mirror_distributions <- function( na.rm = na.rm ) + if (is_categorical) { - ggplot2::facet_grid(comparison ~ method, scales = "free_y") + ggplot2::facet_grid(comparison ~ method, scales = facet_scales) } else { - ggplot2::facet_wrap(~method, scales = "free_y") + ggplot2::facet_wrap(~method, scales = facet_scales) } } } else { @@ -272,7 +277,7 @@ plot_mirror_distributions <- function( # Add faceting for categorical exposures without weights if (is_categorical) { - p <- p + ggplot2::facet_wrap(~comparison, scales = "free_y") + p <- p + ggplot2::facet_wrap(~comparison, scales = facet_scales) } } diff --git a/man/plot_mirror_distributions.Rd b/man/plot_mirror_distributions.Rd index 015c5e3..c9df3cf 100644 --- a/man/plot_mirror_distributions.Rd +++ b/man/plot_mirror_distributions.Rd @@ -18,7 +18,8 @@ plot_mirror_distributions( include_unweighted = TRUE, alpha = 0.6, na.rm = FALSE, - .reference_level = 1L + .reference_level = 1L, + facet_scales = "fixed" ) } \arguments{ @@ -59,6 +60,11 @@ distribution? Defaults to TRUE.} \item{.reference_level}{The reference group level for categorical exposures (>2 levels). Can be a string (group level) or numeric (position). Defaults to 1 (first level). Only used when .exposure has more than 2 levels.} + +\item{facet_scales}{Character. Scale specification for facets. Defaults to +"fixed" to match ggplot2's default behavior. Options are +"fixed", "free_x", "free_y", or "free". Use "free_y" to allow different +y-axis scales across panels, which was the previous default behavior.} } \value{ A ggplot2 object. diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-custom-reference.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-custom-reference.svg index 7f6a8d2..775ae48 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/categorical-custom-reference.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-custom-reference.svg @@ -18,240 +18,219 @@ - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - -lt_12_per_year vs daily + + +lt_12_per_year vs daily - - + + - - -none vs daily + + +none vs daily - - + + - - -1_4_per_month vs daily + + +1_4_per_month vs daily - - + + - - -2_3_per_week vs daily + + +2_3_per_week vs daily - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -0.02 -0 -0.02 - - - -0.02 -0 -0.02 -0.04 - - - - -0.02 -0 -0.02 - - - -0.03 -0.02 -0.01 -0 -0.01 -0.02 -0.03 - - - - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +0.02 +0 +0.02 +0.04 + + + + +0.02 +0 +0.02 +0.04 + + + + age Density diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-density.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-density.svg index 25916d5..b29f525 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-density.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-density.svg @@ -18,219 +18,203 @@ - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - -daily vs none + + +daily vs none - - + + - - -lt_12_per_year vs none + + +lt_12_per_year vs none - - + + - - -1_4_per_month vs none + + +1_4_per_month vs none - - + + - - -2_3_per_week vs none + + +2_3_per_week vs none - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -0.04 -0.02 -0 -0.02 - - - - -0.04 -0.02 -0 -0.02 - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 0.04 0.02 0 @@ -239,14 +223,14 @@ -0.04 -0.02 -0 -0.02 - - - - +0.04 +0.02 +0 +0.02 + + + + age Density diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-histogram.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-histogram.svg index add9aef..6fc676d 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-histogram.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-histogram.svg @@ -18,387 +18,347 @@ - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - -daily vs none + + +daily vs none - - + + - - -lt_12_per_year vs none + + +lt_12_per_year vs none - - + + - - -1_4_per_month vs none + + +1_4_per_month vs none - - + + - - -2_3_per_week vs none + + +2_3_per_week vs none - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -30 -20 -10 -0 -10 -20 - - - - - - -30 -20 -10 -0 -10 -20 -30 - - - - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 25 0 25 @@ -407,20 +367,14 @@ -30 -20 -10 -0 -10 -20 -30 - - - - - - - +25 +0 +25 +50 + + + + age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-fixed-scales.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-fixed-scales.svg new file mode 100644 index 0000000..b73b30d --- /dev/null +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-fixed-scales.svg @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +daily vs none + + + + + + + + + + +lt_12_per_year vs none + + + + + + + + + + +1_4_per_month vs none + + + + + + + + + + +2_3_per_week vs none + + + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +0.04 +0.02 +0 +0.02 + + + + +0.04 +0.02 +0 +0.02 + + + + +age +Density + +alcoholfreq_cat + + + + + + + + + + +none +lt_12_per_year +1_4_per_month +2_3_per_week +daily +categorical fixed scales + + diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-free-y-scales.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-free-y-scales.svg new file mode 100644 index 0000000..479c6d9 --- /dev/null +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-free-y-scales.svg @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +daily vs none + + + + + + + + + + +lt_12_per_year vs none + + + + + + + + + + +1_4_per_month vs none + + + + + + + + + + +2_3_per_week vs none + + + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +0.04 +0.02 +0 +0.02 + + + + +0.04 +0.02 +0 +0.02 + + + + +0.04 +0.02 +0 +0.02 + + + + +0.04 +0.02 +0 +0.02 + + + + +age +Density + +alcoholfreq_cat + + + + + + + + + + +none +lt_12_per_year +1_4_per_month +2_3_per_week +daily +categorical free_y scales + + diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-multiple-weights.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-multiple-weights.svg index d3e0bb8..dc9705b 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/categorical-multiple-weights.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-multiple-weights.svg @@ -60,29 +60,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -93,29 +93,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -126,29 +126,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -192,29 +192,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -225,29 +225,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -258,29 +258,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -324,29 +324,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -357,29 +357,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -390,29 +390,29 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -530,30 +530,30 @@ -0.04 -0.02 -0 -0.02 - - - - -0.04 -0.02 -0 -0.02 - - - - -0.04 -0.02 -0 -0.02 - - - - +0.04 +0.02 +0 +0.02 + + + + +0.04 +0.02 +0 +0.02 + + + + +0.04 +0.02 +0 +0.02 + + + + age Density diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-no-unweighted.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-no-unweighted.svg index 868b0c7..99b8a2c 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/categorical-no-unweighted.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-no-unweighted.svg @@ -27,33 +27,33 @@ - - - - - - + + + + + + - - - - - - + + + + + + - - - - + + + + @@ -101,32 +101,33 @@ - - - - - - + + + + + + - - - - - + + + + + + - - - - + + + + @@ -137,33 +138,33 @@ - - - - - - + + + + + + - - - - - - + + + + + + - - - - + + + + @@ -231,18 +232,18 @@ 50 60 70 -0.02 -0.01 -0 -0.01 -0.02 -0.03 - - - - - - +0.02 +0.01 +0 +0.01 +0.02 +0.03 + + + + + + 0.02 0.01 0 @@ -255,28 +256,30 @@ -0.02 -0.01 -0 -0.01 -0.02 - - - - - -0.02 -0.01 -0 -0.01 -0.02 -0.03 - - - - - - +0.02 +0.01 +0 +0.01 +0.02 +0.03 + + + + + + +0.02 +0.01 +0 +0.01 +0.02 +0.03 + + + + + + age Density diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-with-weights.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-with-weights.svg index 441a80d..8e70533 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/categorical-with-weights.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-with-weights.svg @@ -27,65 +27,60 @@ - - - - - - + + + + - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -160,66 +155,60 @@ - - - - - - + + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -230,65 +219,60 @@ - - - - - - + + + + - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -299,65 +283,60 @@ - - - - - - + + + + - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -432,66 +411,60 @@ - - - - - - + + + + - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -502,65 +475,60 @@ - - - - - - + + + + - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -645,50 +613,30 @@ 80 120 160 -300 -200 -100 -0 -100 -200 - - - - - - +200 +0 +200 + + + 200 0 200 -300 -200 -100 -0 -100 -200 -300 - - - - - - - -300 -200 -100 -0 -100 -200 - - - - - - +200 +0 +200 + + + +200 +0 +200 + + + wt71 Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/fixed-facet-scales-default.svg b/tests/testthat/_snaps/plot_mirror_distributions/fixed-facet-scales-default.svg new file mode 100644 index 0000000..0fdec71 --- /dev/null +++ b/tests/testthat/_snaps/plot_mirror_distributions/fixed-facet-scales-default.svg @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +observed + + + + + + + + + + +w_ate + + + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + +age +Count + +qsmk + + + + +0 +1 +fixed facet scales default + + diff --git a/tests/testthat/_snaps/plot_mirror_distributions/free-facet-scales.svg b/tests/testthat/_snaps/plot_mirror_distributions/free-facet-scales.svg new file mode 100644 index 0000000..cae3eed --- /dev/null +++ b/tests/testthat/_snaps/plot_mirror_distributions/free-facet-scales.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +observed + + + + + + + + + + +w_ate + + + + + + + + + + +w_att + + + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +25 +0 +25 + + + +100 +0 +100 + + + +120 +80 +40 +0 +40 + + + + + +age +Count + +qsmk + + + + +0 +1 +free facet scales + + diff --git a/tests/testthat/_snaps/plot_mirror_distributions/free-y-facet-scales.svg b/tests/testthat/_snaps/plot_mirror_distributions/free-y-facet-scales.svg new file mode 100644 index 0000000..02ffbef --- /dev/null +++ b/tests/testthat/_snaps/plot_mirror_distributions/free-y-facet-scales.svg @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +observed + + + + + + + + + + +w_ate + + + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + +120 +80 +40 +0 +40 + + + + + +age +Count + +qsmk + + + + +0 +1 +free_y facet scales + + diff --git a/tests/testthat/_snaps/plot_mirror_distributions/multiple-weights.svg b/tests/testthat/_snaps/plot_mirror_distributions/multiple-weights.svg index cdf850d..83ce259 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/multiple-weights.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/multiple-weights.svg @@ -21,295 +21,277 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - -observed + + +observed - - + + - - -w_ate + + +w_ate - - + + - - -w_att + + +w_att - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -25 -0 -25 - - - -100 -0 -100 - - - -120 -80 -40 -0 -40 - - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/weighted-density.svg b/tests/testthat/_snaps/plot_mirror_distributions/weighted-density.svg index 52bab1f..114f288 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/weighted-density.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/weighted-density.svg @@ -18,139 +18,125 @@ - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - -observed + + +observed - - + + - - -w_ate + + +w_ate - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -0.03 -0.02 -0.01 -0 -0.01 -0.02 -0.03 - - - - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 0.03 0.02 0.01 diff --git a/tests/testthat/_snaps/plot_mirror_distributions/weighted-histogram-default.svg b/tests/testthat/_snaps/plot_mirror_distributions/weighted-histogram-default.svg index 43b493f..e956643 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/weighted-histogram-default.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/weighted-histogram-default.svg @@ -21,200 +21,188 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - -observed + + +observed - - + + - - -w_ate + + +w_ate - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -100 -0 -100 - - - -120 -80 -40 -0 -40 - - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + age Count diff --git a/tests/testthat/test-plot_mirror_distributions.R b/tests/testthat/test-plot_mirror_distributions.R index 3d82170..4891161 100644 --- a/tests/testthat/test-plot_mirror_distributions.R +++ b/tests/testthat/test-plot_mirror_distributions.R @@ -340,3 +340,62 @@ test_that("plot_mirror_distributions validates categorical reference group", { "halfmoon_range_error" ) }) + +test_that("plot_mirror_distributions respects facet_scales parameter", { + # Test default fixed scales + p_fixed <- plot_mirror_distributions( + nhefs_weights, + age, + qsmk, + .weights = w_ate, + bins = 20 + ) + + expect_s3_class(p_fixed, "ggplot") + expect_doppelganger("fixed facet scales default", p_fixed) + + # Test free_y scales (previous default behavior) + p_free_y <- plot_mirror_distributions( + nhefs_weights, + age, + qsmk, + .weights = w_ate, + facet_scales = "free_y", + bins = 20 + ) + + expect_doppelganger("free_y facet scales", p_free_y) + + # Test with categorical exposure + p_cat_fixed <- plot_mirror_distributions( + nhefs_weights, + age, + alcoholfreq_cat, + type = "density" + ) + + expect_doppelganger("categorical fixed scales", p_cat_fixed) + + # Test categorical with free_y + p_cat_free <- plot_mirror_distributions( + nhefs_weights, + age, + alcoholfreq_cat, + type = "density", + facet_scales = "free_y" + ) + + expect_doppelganger("categorical free_y scales", p_cat_free) + + # Test other scale options + p_free <- plot_mirror_distributions( + nhefs_weights, + age, + qsmk, + .weights = c(w_ate, w_att), + facet_scales = "free", + bins = 20 + ) + + expect_doppelganger("free facet scales", p_free) +}) From 1395cebc40f67922f3732deffde302cd89bff182 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Mon, 8 Sep 2025 11:49:00 -0400 Subject: [PATCH 06/14] don't interact a variable with itself --- R/check_balance.R | 58 ++++++- R/utils.R | 29 +++- .../test-check_balance_interactions.R | 153 ++++++++++++++++++ 3 files changed, 229 insertions(+), 11 deletions(-) create mode 100644 tests/testthat/test-check_balance_interactions.R diff --git a/R/check_balance.R b/R/check_balance.R index 2b31735..240fc80 100644 --- a/R/check_balance.R +++ b/R/check_balance.R @@ -122,9 +122,18 @@ check_balance <- function( # Extract just the variables we're working with vars_data <- dplyr::select(.data, dplyr::all_of(var_names)) + # Track variable origins for interaction filtering + dummy_var_mapping <- list() + # Create dummy variables if requested if (make_dummy_vars) { - vars_data <- create_dummy_variables(vars_data, binary_as_single = TRUE) + dummy_result <- create_dummy_variables( + vars_data, + binary_as_single = TRUE, + return_mapping = TRUE + ) + vars_data <- dummy_result$data + dummy_var_mapping <- dummy_result$mapping } # Add squared terms if requested @@ -206,13 +215,32 @@ check_balance <- function( } # Prepare variables for interactions - interaction_vars <- purrr::imap( + interaction_vars_list <- purrr::imap( original_numeric, prepare_interaction_variable, binary_categorical_names = binary_categorical_names, original_vars_data = original_vars_data - ) |> - purrr::flatten() + ) + + # Extract the variables and update mapping for expanded binaries + interaction_vars <- purrr::flatten(interaction_vars_list) + + # Update mapping for any expanded binary categoricals + for (i in seq_along(interaction_vars_list)) { + var_result <- interaction_vars_list[[i]] + var_name <- names(original_numeric)[i] + + # Check if this variable was expanded (binary categorical) + if (var_name %in% binary_categorical_names) { + # The result is already flattened by prepare_interaction_variable + # Get the names of the expanded dummies + expanded_names <- names(var_result) + for (expanded_name in expanded_names) { + # Track that this expanded dummy came from the original variable + dummy_var_mapping[[expanded_name]] <- var_name + } + } + } # Now create interactions between all pairs var_combinations <- utils::combn( @@ -224,7 +252,7 @@ check_balance <- function( # Filter out same-variable dummy interactions (e.g., sex0 x sex1) valid_combinations <- purrr::keep( var_combinations, - is_valid_interaction_combo + \(combo) is_valid_interaction_combo(combo, dummy_var_mapping) ) # Create interaction terms using functional programming @@ -234,9 +262,12 @@ check_balance <- function( interaction_vars = interaction_vars ) - # Flatten the list and add to vars_data + # Flatten the list and convert to data frame interaction_terms <- purrr::flatten(interaction_terms) - vars_data <- c(vars_data, interaction_terms) + if (length(interaction_terms) > 0) { + interaction_df <- dplyr::as_tibble(interaction_terms) + vars_data <- dplyr::bind_cols(vars_data, interaction_df) + } } } } @@ -568,10 +599,21 @@ prepare_interaction_variable <- function( } # Check if an interaction combination is valid (not between same variable dummies) -is_valid_interaction_combo <- function(combo) { +is_valid_interaction_combo <- function(combo, variable_mapping = NULL) { var1 <- combo[1] var2 <- combo[2] + # If we have a mapping, use it to determine if variables come from same source + if (!is.null(variable_mapping)) { + # Get the original variable for each dummy (or the variable itself if not a dummy) + origin1 <- variable_mapping[[var1]] %||% var1 + origin2 <- variable_mapping[[var2]] %||% var2 + + # Only keep interactions between different original variables + return(origin1 != origin2) + } + + # Fallback to the old regex approach if no mapping provided # Extract base variable names (before dummy suffixes) base1 <- sub("^([^0-9]+).*", "\\1", var1) base2 <- sub("^([^0-9]+).*", "\\1", var2) diff --git a/R/utils.R b/R/utils.R index fb3f4ed..48bf232 100644 --- a/R/utils.R +++ b/R/utils.R @@ -188,7 +188,11 @@ utils::globalVariables(c( #' variable representations #' #' @noRd -create_dummy_variables <- function(data, binary_as_single = TRUE) { +create_dummy_variables <- function( + data, + binary_as_single = TRUE, + return_mapping = FALSE +) { # Identify categorical variables (factors and character variables) categorical_vars <- purrr::map_lgl( data, @@ -197,7 +201,11 @@ create_dummy_variables <- function(data, binary_as_single = TRUE) { if (!any(categorical_vars)) { # No categorical variables, return data as-is - return(data) + if (return_mapping) { + return(list(data = data, mapping = list())) + } else { + return(data) + } } # Extract categorical and non-categorical data @@ -211,6 +219,9 @@ create_dummy_variables <- function(data, binary_as_single = TRUE) { -dplyr::where(\(x) is.factor(x) || is.character(x)) ) + # Track dummy variable mapping + dummy_mapping <- list() + # Create dummy variables using functional programming dummy_vars <- purrr::imap( categorical_data, @@ -233,6 +244,8 @@ create_dummy_variables <- function(data, binary_as_single = TRUE) { col_factor <- factor(col_data, levels = levels_to_use) dummy_values <- as.numeric(col_factor) - 1 } + # Track that this dummy came from the original variable + dummy_mapping[[col_name]] <<- col_name stats::setNames(list(dummy_values), col_name) } else { # Multi-level variable or binary with binary_as_single = FALSE: @@ -242,6 +255,10 @@ create_dummy_variables <- function(data, binary_as_single = TRUE) { levels_to_use, \(x) as.numeric(col_data == x) ) + # Track that all these dummies came from the original variable + for (dummy_name in dummy_names) { + dummy_mapping[[dummy_name]] <<- col_name + } stats::setNames(dummy_values, dummy_names) } } @@ -251,7 +268,13 @@ create_dummy_variables <- function(data, binary_as_single = TRUE) { dummy_df <- dplyr::as_tibble(purrr::flatten(dummy_vars)) # Combine non-categorical and dummy variables - dplyr::bind_cols(non_categorical_data, dummy_df) + result_data <- dplyr::bind_cols(non_categorical_data, dummy_df) + + if (return_mapping) { + return(list(data = result_data, mapping = dummy_mapping)) + } else { + return(result_data) + } } # Create a signature for a group based on aesthetic columns diff --git a/tests/testthat/test-check_balance_interactions.R b/tests/testthat/test-check_balance_interactions.R new file mode 100644 index 0000000..1f8e69a --- /dev/null +++ b/tests/testthat/test-check_balance_interactions.R @@ -0,0 +1,153 @@ +test_that("check_balance does not create interactions between levels of same variable", { + # Create test data with various factor types + test_data <- data.frame( + # Binary factors with text levels + sex = factor(c(rep("male", 50), rep("female", 50))), + race = factor(c(rep("white", 40), rep("black", 60))), + employment = factor(c(rep("employed", 45), rep("unemployed", 55))), + # Binary factor with numeric-like levels + treatment = factor(c(rep("0", 50), rep("1", 50))), + # Continuous variable + age = rnorm(100, 50, 10), + # Multi-level factor + education = factor(sample(c("high", "medium", "low"), 100, replace = TRUE)), + # Outcome + outcome = c(rep(0, 50), rep(1, 50)) + ) + + # Run check_balance with interactions + result <- check_balance( + test_data, + c(sex, race, employment, age, education), + outcome, + interactions = TRUE, + .metrics = "smd" + ) + + # Get all interaction variables + interaction_vars <- unique(result$variable)[grepl( + "_x_", + unique(result$variable) + )] + + # Check that no self-interactions exist + + # Sex should not interact with itself + sex_self <- interaction_vars[grepl("sex.*_x_sex", interaction_vars)] + expect_length(sex_self, 0) + + # Race should not interact with itself + race_self <- interaction_vars[grepl("race.*_x_race", interaction_vars)] + expect_length(race_self, 0) + + # Employment should not interact with itself + employment_self <- interaction_vars[grepl( + "employ.*_x_employ", + interaction_vars + )] + expect_length(employment_self, 0) + + # Education (multi-level) should not interact with itself + education_self <- interaction_vars[grepl( + "education.*_x_education", + interaction_vars + )] + expect_length(education_self, 0) + + # But different variables should interact + expect_true(any(grepl("age_x_sex", interaction_vars))) + expect_true(any(grepl("age_x_race", interaction_vars))) + expect_true(any(grepl("sex.*_x_race", interaction_vars))) + expect_true(any(grepl("age_x_education", interaction_vars))) +}) + +test_that("is_valid_interaction_combo works with mapping", { + # Direct test of the helper function + # Note: This requires access to the internal function + check_combo <- halfmoon:::is_valid_interaction_combo + + # Test with mapping (the primary approach) + mapping <- list( + sex0 = "sex", + sex1 = "sex", + sexmale = "sex", + sexfemale = "sex", + race0 = "race", + race1 = "race", + racewhite = "race", + raceblack = "race", + employedemployed = "employed", + employedunemployed = "employed", + marriedmarried = "married", + marriedsingle = "married", + sex_male = "sex", + sex_female = "sex", + race_white = "race", + race_black = "race", + age = "age", + educationhigh = "education", + var0 = "var0", + var1 = "var1" + ) + + # Same variable - should return FALSE with mapping + expect_false(check_combo(c("sex0", "sex1"), mapping)) + expect_false(check_combo(c("race0", "race1"), mapping)) + expect_false(check_combo(c("sexmale", "sexfemale"), mapping)) + expect_false(check_combo(c("racewhite", "raceblack"), mapping)) + expect_false(check_combo( + c("employedemployed", "employedunemployed"), + mapping + )) + expect_false(check_combo(c("marriedmarried", "marriedsingle"), mapping)) + expect_false(check_combo(c("sex_male", "sex_female"), mapping)) + expect_false(check_combo(c("race_white", "race_black"), mapping)) + + # Different variables - should return TRUE with mapping + expect_true(check_combo(c("var0", "var1"), mapping)) + expect_true(check_combo(c("age", "sex0"), mapping)) + expect_true(check_combo(c("sexmale", "racewhite"), mapping)) + expect_true(check_combo(c("age", "educationhigh"), mapping)) + expect_true(check_combo(c("sex0", "race1"), mapping)) + expect_true(check_combo(c("employedemployed", "sexmale"), mapping)) + + # Test fallback to regex when no mapping provided + # The regex approach is less sophisticated and only handles numeric suffixes + expect_false(check_combo(c("sex0", "sex1"), NULL)) + expect_false(check_combo(c("race0", "race1"), NULL)) +}) + +test_that("interaction creation handles edge cases correctly", { + # Test with variables that might confuse the pattern matching + tricky_data <- data.frame( + # Variable names that contain suffixes within them + female_headed = factor(c(rep("yes", 50), rep("no", 50))), + male_presence = factor(c(rep("present", 60), rep("absent", 40))), + # Variable that ends with a number + var1 = rnorm(100), + var2 = rnorm(100), + # Outcome + y = rbinom(100, 1, 0.5) + ) + + result <- check_balance( + tricky_data, + c(female_headed, male_presence, var1, var2), + y, + interactions = TRUE, + .metrics = "smd" + ) + + interaction_vars <- unique(result$variable)[grepl( + "_x_", + unique(result$variable) + )] + + # These should create interactions because they're different variables + expect_true(any(grepl("female_headed.*_x_male_presence", interaction_vars))) + expect_true(any(grepl("var1_x_var2", interaction_vars))) + + # But not self-interactions + expect_false(any(grepl("female_headed.*_x_female_headed", interaction_vars))) + expect_false(any(grepl("male_presence.*_x_male_presence", interaction_vars))) +}) From 0c9e2cf72c1e222a3f44ca1f91972e4f351efaf2 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Mon, 8 Sep 2025 11:52:56 -0400 Subject: [PATCH 07/14] don't square binaries --- R/check_balance.R | 30 +++++++++++++++++++++--------- R/compute_balance.R | 4 ---- R/utils.R | 6 ++++++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/R/check_balance.R b/R/check_balance.R index 240fc80..a7d5bcb 100644 --- a/R/check_balance.R +++ b/R/check_balance.R @@ -141,14 +141,21 @@ check_balance <- function( numeric_vars <- purrr::map_lgl(vars_data, is.numeric) if (any(numeric_vars)) { numeric_data <- dplyr::select(vars_data, dplyr::where(is.numeric)) - squared_data <- dplyr::mutate( + # Only square non-binary numeric variables + non_binary_numeric <- dplyr::select( numeric_data, - dplyr::across(everything(), \(x) x^2, .names = "{.col}_squared") - ) - vars_data <- dplyr::bind_cols( - vars_data, - dplyr::select(squared_data, dplyr::ends_with("_squared")) + dplyr::where(\(x) !is_binary(x)) ) + if (ncol(non_binary_numeric) > 0) { + squared_data <- dplyr::mutate( + non_binary_numeric, + dplyr::across(everything(), \(x) x^2, .names = "{.col}_squared") + ) + vars_data <- dplyr::bind_cols( + vars_data, + dplyr::select(squared_data, dplyr::ends_with("_squared")) + ) + } } } @@ -157,14 +164,19 @@ check_balance <- function( numeric_vars <- purrr::map_lgl(vars_data, is.numeric) if (any(numeric_vars)) { numeric_data <- dplyr::select(vars_data, dplyr::where(is.numeric)) - # Only cube original variables, not squared ones + # Only cube original non-binary variables, not squared ones original_numeric <- dplyr::select( numeric_data, -dplyr::ends_with("_squared") ) - if (ncol(original_numeric) > 0) { + # Filter out binary variables + non_binary_original <- dplyr::select( + original_numeric, + dplyr::where(\(x) !is_binary(x)) + ) + if (ncol(non_binary_original) > 0) { cubed_data <- dplyr::mutate( - original_numeric, + non_binary_original, dplyr::across(everything(), \(x) x^3, .names = "{.col}_cubed") ) vars_data <- dplyr::bind_cols( diff --git a/R/compute_balance.R b/R/compute_balance.R index 36976e3..7ddeb15 100644 --- a/R/compute_balance.R +++ b/R/compute_balance.R @@ -110,10 +110,6 @@ bal_smd <- function( res$estimate } -is_binary <- function(x) { - unique_vals <- unique(stats::na.omit(x)) - length(unique_vals) == 2 && all(unique_vals %in% c(0, 1)) -} #' Balance Variance Ratio for Two Groups #' diff --git a/R/utils.R b/R/utils.R index 48bf232..7099bb4 100644 --- a/R/utils.R +++ b/R/utils.R @@ -277,6 +277,12 @@ create_dummy_variables <- function( } } +# Check if a numeric vector is binary (only contains 0 and 1) +is_binary <- function(x) { + unique_vals <- unique(stats::na.omit(x)) + length(unique_vals) == 2 && all(unique_vals %in% c(0, 1)) +} + # Create a signature for a group based on aesthetic columns create_group_signature <- function(group_data, aes_cols) { if (length(aes_cols) > 0) { From ebda371e5199e007abe3c5119d4ee2a382d45c45 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Mon, 15 Sep 2025 06:52:48 -0400 Subject: [PATCH 08/14] check for smd presence --- R/plot_balance.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/plot_balance.R b/R/plot_balance.R index 51ca7c4..4895295 100644 --- a/R/plot_balance.R +++ b/R/plot_balance.R @@ -148,7 +148,7 @@ plot_balance <- function( } # Create caption based on whether we're using absolute values - caption_text <- if (abs_smd) { + caption_text <- if (any(.df$metric %in% "smd") && abs_smd) { "smd values shown as absolute values" } else { NULL From da6fa0ef2aa1da8d39bd8062bf21b053c5daf225 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Mon, 3 Nov 2025 14:06:30 -0500 Subject: [PATCH 09/14] compatibility with ggplot2 4.0.0 --- R/geom_mirrored_histogram.R | 6 +- README.Rmd | 4 +- README.md | 8 +- man/figures/README-example-1.png | Bin 19566 -> 19239 bytes man/figures/README-qq-example-1.png | Bin 51160 -> 51158 bytes man/figures/README-unnamed-chunk-6-1.png | Bin 18404 -> 17408 bytes .../autoplot-halfmoon-calibration.svg | 1 + .../autoplot-methods/autoplot-halfmoon-qq.svg | 1 + .../plot-halfmoon-calibration.svg | 1 + .../autoplot-methods/plot-halfmoon-qq.svg | 1 + .../geom_mirrored_density/fill-with-theme.svg | 1 + .../layered-weighted-and-unweighted.svg | 438 ++++--- .../_snaps/geom_qq2/geom-qq2-basic.svg | 2 +- .../geom_qq2/geom-qq2-custom-quantiles.svg | 2 +- .../geom_qq2/geom-qq2-multiple-weights.svg | 2 +- .../_snaps/geom_qq2/geom-qq2-weighted.svg | 2 +- .../balance-plot-categorical-ks-only.svg | 257 +++-- .../balance-plot-variance-ratio.svg | 103 +- .../basic-histogram.svg | 153 ++- .../categorical-exposure-histogram.svg | 556 ++++----- .../categorical-with-weights.svg | 1016 +++++++++-------- .../custom-aesthetics.svg | 153 ++- .../fixed-facet-scales-default.svg | 284 ++--- .../free-facet-scales.svg | 452 ++++---- .../free-y-facet-scales.svg | 301 +++-- .../mirror-x-axis.svg | 153 ++- .../multiple-weights.svg | 420 +++---- .../no-unweighted.svg | 148 +-- .../weighted-histogram-default.svg | 284 ++--- .../testthat/_snaps/plot_qq/basic-qq-plot.svg | 2 +- .../plot_qq/qq-plot-multiple-weights.svg | 2 +- .../_snaps/plot_qq/qq-plot-no-observed.svg | 2 +- .../plot_qq/qq-plot-propensity-score.svg | 2 +- .../_snaps/plot_qq/qq-plot-with-weight.svg | 2 +- .../testthat/test-plot_mirror_distributions.R | 4 +- tests/testthat/test-plot_roc.R | 3 - 36 files changed, 2406 insertions(+), 2360 deletions(-) diff --git a/R/geom_mirrored_histogram.R b/R/geom_mirrored_histogram.R index c7ac3cf..7e18bfb 100644 --- a/R/geom_mirrored_histogram.R +++ b/R/geom_mirrored_histogram.R @@ -94,8 +94,7 @@ StatMirrorCount <- ggplot2::ggproto( pad = FALSE, breaks = NULL, flipped_aes = FALSE, - origin = NULL, - right = NULL, + ..., drop = NULL ) { # Check for no group @@ -130,8 +129,7 @@ StatMirrorCount <- ggplot2::ggproto( pad = pad, breaks = breaks, flipped_aes = flipped_aes, - origin = origin, - right = right, + ..., drop = drop ) diff --git a/README.Rmd b/README.Rmd index 6c7ffcb..5c989b8 100644 --- a/README.Rmd +++ b/README.Rmd @@ -59,7 +59,7 @@ library(ggplot2) # weighted mirrored histograms ggplot(nhefs_weights, aes(.fitted)) + geom_mirror_histogram( - aes(exposure = qsmk), + aes(group = qsmk), bins = 50 ) + geom_mirror_histogram( @@ -229,7 +229,7 @@ matches$ps <- m.out1$distance ggplot(matches, aes(ps)) + geom_mirror_histogram( - aes(exposure = factor(treat)), + aes(group = factor(treat)), bins = 50 ) + geom_mirror_histogram( diff --git a/README.md b/README.md index d935480..95f705a 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ library(ggplot2) # weighted mirrored histograms ggplot(nhefs_weights, aes(.fitted)) + geom_mirror_histogram( - aes(exposure = qsmk), + aes(group = qsmk), bins = 50 ) + geom_mirror_histogram( @@ -60,8 +60,6 @@ ggplot(nhefs_weights, aes(.fitted)) + bins = 50, alpha = 0.5 ) + scale_y_continuous(labels = abs) -#> Warning in ggplot2::geom_histogram(mapping = mapping, data = data, stat = -#> StatMirrorCount, : Ignoring unknown aesthetics: exposure ``` @@ -275,7 +273,7 @@ matches$ps <- m.out1$distance ggplot(matches, aes(ps)) + geom_mirror_histogram( - aes(exposure = factor(treat)), + aes(group = factor(treat)), bins = 50 ) + geom_mirror_histogram( @@ -283,8 +281,6 @@ ggplot(matches, aes(ps)) + bins = 50, alpha = 0.5 ) + scale_y_continuous(labels = abs) -#> Warning in ggplot2::geom_histogram(mapping = mapping, data = data, stat = -#> StatMirrorCount, : Ignoring unknown aesthetics: exposure ``` diff --git a/man/figures/README-example-1.png b/man/figures/README-example-1.png index 48ab000844c3fb7771c5299e6d314d3d2b869103..77e54c6e73a0e61d08f93fdd2b99b51231dddf62 100644 GIT binary patch literal 19239 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 literal 51160 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 l_eTgr40L$uq@=73kMc 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 E1L5(*vH$=8 literal 18404 zcmeHvXHZmKw`LPW5EW1m1PO|OWKaYpwgHfg18-uuRdk$4N%Td4h1 z3wCkJd*t6U$3w@DbicD*eV&5};QokI{z&M1W4nDDpRh$M5j=bMSU<&fsv4a8^7z)Q{>x%o0=m zXy0b>){)tKuCg?q-^lC!Pj{NGO`1Xusp`J!dlTN<`$^LGbep7B#43(y@7ku%lldk3~Tp`H^X<1<49CM8CY^wf&hD@mgbb z_lhgCj#=449p5-Jx}(j=$9!F#zKb^1FFxEa+4cvFofEA5Ah~wnkNxK$8w(+4Hv>BCa`@td(|jyWugbBnkyo1kAeJt3Na|i5f??)yXCbk@vUt zw^=rY_t_W-!)-JJ%B3_C%X=Nrj@Qj-pL09@9PEy_Z#(*7IMesVa7IYy?BQuo03oQz{_lPYo*u36ivj_xYezm6r_CAzOAu~&)5usm%5e{n-S^m|K4hp2(fJ3 z3SngRLXG|wpJ;VRv`@4f^Zuzn&SP(AZ)nHpkSP7U+igj}axpI@|ID;SQc$%VPmm zj~7Fm_Eq#N^Pv*lMh($5!0nomK#xZk|< z!&c_-fO^O+&D0^0=*~Wy$d*pgU9#~{1nqm~&4S)$sLCbCC-HRGO%+$R+NWdqcY1tl zzH2Jcw&gI+Z|J((u#7_bJt_^3_6}h1HG=LjNJ-KW!4ZoqX`OLzGjI@hOtoa5DJVcV zz-M9z-dhU@A^3y`erUlD)|cSpuHYvn5#T=Kjbp#OU^p}kfj}WL5AUhD;$cQe;qoAEu0m2Wz7{rF{%xZ;R&BOHYUP{k{>hu z;wB01c*J`WGTwN}d+plGpLEO!C=-d>f<(1}S%0I=S22-W<*H(1haMpqG&(nTR|B(P zo1K%hN7T#Jc;6d>hfhdM&IC1zBV-Nga*KO|yWkDI$^_{l$A0(crh0WKL^yX?Q4046 z_?GDZ_*Z) zN(x0$!={?TxmBfWf*d2bv^(u})E^nu2VQ1>**4W2shNC-JM!wFv`0sWI1zgxqMr4( z!}PC7(%4P@+0L;sL)Yzn*M%*XUIy4~^7nIMhezw^E>a)oA_TEHw;O2*VWP`Hqu8;m zm_+dK%$?O)YyL>i8{$)OiZIEoFLC(dv8=vcB=>%%X?j!sSXMuEp^%vW?*~Z#9S<*M z1J>d*On82Kn@!eqC)QRpz1y>NQLR3Cj;ORZ-lLc&=`_;m0XxpBhy{R^S>re79*YtW z|1&8uR97er|5(=E(2Mx>-hw`+npiu{%=PAv?)j|CGB1uNmNcTtX8-V5#F?=ExWRD+H{>3n{KGNa5Xve^zkaWL=oT7tm2afPNO^yAC7#8jCo`Qn zej%7XsYxG!uyK8$05EqLUVYh3)26U%@dE{Bh}-XE>8aBR2ng6cxY;cjgFZw58h$_< z;$EaoDAC@{-MzijLP+$H^KKF6=bLExc;Q0w8wE?|YM4jHNC(H=1D(AnaX4&9vCw|1 zsVI#l`5nbi9tiyR2Wb@%+R@=shXBV*yauBDtNPBp#G;y?b;2Wf4M$Dy#zrkX+#^Pu zW^grndb8cstVf)d)1)=-ZXI>e-coh-N)Q8_%E!#ZN59BQTldr;dMFp!l&VTf+q@t` zt0mG&gSis#DS_WsRaJ#_M0Xa&XUBiH8oJ4noKC3s($>GZ^&ici0h*<96g|5!0?nQG{amW6Qj~~43e{+M){TLb-GZw4`pFPzy`fI&wEAIUhv`O^0Z4#hK z2}`qUe|;e_xfU~Ue`o*K?$79Krr_Uu2f4oV$uQbD_=hkna|5I8$yQ3cdOVC{C0Ou$ z&Lbj{QviOO*6ej{T4KR~|Y;``|xGq5A#|fg63(WdoZ=fL%#+y}? z0m`wta6@FVTs~naS|fUG;4Q>Q6ijwn+tywI=WoH>Vyt@_?;M*NlM)b0!Uk&}ZmU}X zhdrPXABeNGRmv9^Rfsk;o+($$Ox((Rq-_=JJ@&5Xv9r^C)49?d()KsM!f!7NC7tUJ zq0t0NL^WYdPV5?A+4}gsAdKpPk^kk}dT+%SbT>q*%#c<^obes4C^$YdNtlI~I%A4P zz0vjZ4@K%D&r@#>^~OM>H#77LpDoO8o|(n7&dcb=sgO{Lg4{b8|F`wAv>-m4K-NR^ z?6*%YJSHSeN`bh=9?Kq@REckMpVl|y`>3xu3d1)#L-(L7bNH(1FHX%_iZcSE=TYz~ z3V*AMKtRGAz$K?tT)=wnKl0K7(W0`3_ zRsJA6K5$2yE%9b<8gFc#U5gr>l194CpsTP91=E)ZX!O|kuZa&Z@|K^iU<1tf`W*zY znsY*_wqAQfXkM=!Im8!E)?-B_xtwAZg@|F0U7gb6s~^?_4EL{99&Y3*6_3I!mwMlX z;1mXf8r|ppK4#y{jc(%1lQ%qEjqFO53GIAMZ4gzp{F*n_rFw5f44UVM)A%T5R6AsS zI@VUPeBrAcg$L2mV);@65BTLxOv&uWfX*3-qn+KNS?&?%A?x|PhO(Q$MGFA;EZ{WP zozI#-iV_?!3Eij~%>BM+Xjvvmds^ z-7T=LgROT+4@E@0VwEzwPtabzSjK6M?2y_Bu`QW+gC2EX`dl3x-Xb{kiCD#wE<+(U zLgSOxWB0q$i5)0mK0ZFK&&53ZJyBg(VB_~r(+jLm3HOZ&7kI@lsZRv8RqlQ%qC$PP zmd&zC7<8)oI$$GR&f}ijzx0FI@YdWS%9`)_o0$G&E3rtKn`Un{y%tGRF6GPX(%hyH zkhZr#=T?GM>3WQ}Q_wPQtUQ ztNEFR+?Og<_j9-dE^*5SQ1j+iURi4^b(l%NV<^%|>%e;Dk&&Nw(H+8?=R<_ZoIjgq zM6azYLx~p#jpWfE6s&pF6;k}|)#xiEIz2XhZ?Qa&hh{$3w#x0Gkm|&e=SbwuA!Q8= z?y2*+sYpj7n+AN!*ruz?A4}3hYh0n zi4yzj;m_Dn?X9s-n&NoBHOCcL>6mi7;IgPw2wh@lNeTyD>Iub&5b#WzCW zE8?LZ8LY>Db$ww(Kt_f@dgv*Ki$BebWv~Kv_8~%zIMyBJ}dlkTVE^3jnIrZ z@PCC|0JH#qe)nK*X^FSKmPfbfQ#Z}%vo=dFe8Oxt;3;5E*$;7>D)$m_3{D$APZA;+ zSm#_%)&*R~RHg%Rtezfb2iy~LBqb#5zQRr^Dn#LG9bCOO!qNQ3QrMC}r^>^vK~6`+ ztU>8FAw9(nRWDOpMJqEM(=#HYGn}Dpd*qqfAjW6+ezHFqT@8$$M#Zd)8$BDi#T=c2 zCP`cdr-Ek;Ek`~zv79`0{%HRc+UGPw)OO%cJfHKVVVC#%C%7C%cbvoX<%J8(+7ziP zrk8^w8%cCRp!Kv#FSk_rig$SHX?}DJ~kSpefbD1VU#w}kuO`?z8@B0Gp z*!T9imFK4_e=+TykB3z@I$Kut##-23_?rvX5UzWlXU_LIao3^X4T^KJC;rN`#f`~YDg9Vp9Gbu}bQ+R~C!}{W~GKhY%e$XO(7_{KC@MYXef3t&? z7L5Lm!L9VOH$-44JJb#*ssxa&gHRmaRJdXko~`)$?~X|UR!SfK^ZdztFqB||s;W9C z7gB)gq*=Za90vk#s0aw8nC`GkxC`GhfruWzTfjvrrglZJ1d-cmIAt^Of%MT)?V89* zZGlt;_Mxa?fwLFlKn^Cz|NUwBuw&%q|E|PH^wjw{uT9s4)>2|}^H8WW-YhmMb!VyS z@^~5=8a~(5;WkTezF_{=Hj*j}y)ehyMA~(wMcB_-fw5vF{D7Pq~GB7Vz86zhTT>DLm@GekY>)tzkyr#v7`J z%r|G|B8nXfV^{Tuq|jHp)7ySSy?AL(NAbdf5mAWH>Jlds+lOCv%sgOBWW*RuZncFJ zL-%wg--=<~oJOwRz^e8nnRIG_Nn=PvSGEqmJW+MjC!Ipsy=_ZW0@$l(5Zea@sRGu6 z$ZL>|@|*p%pe`Xrm^MdPFjx{k7lRKr7&&0;kd-MDbZ45iCF6&57F&=BPU(BuD;=BP zPeqWQ>4!J+9V?f~7N~M`gKg{B9DEjlxelmDpT&jyRp4l*|2@EeR|e@Ok;a#8WX8Yk zm?2#E125m|%vR6oT%Br`_861G?bveQi;Cn_gip3&8W4UOC<;$}1rN|p`Sr9D=biwN>ah6HuSLDUC)q+*8uf< z@ZIUC-6@dMR^6p{8Mc$O9l!eaN(jiC5vkIQaHPRz_5Ktux`y%ah45^WZzl;`-20Ez zw<8dq>nZ36T^kw0qusu)Mz%yfs{mx%-I=)cCe5mwmEakrj0D(oo&2YgD+c@2m1$%9 z(?VTCqnkzRF?|)RBQI*sv9CI{iEX8dZT6@1+hQCef$JDuej}8clUG$XTM3^L8H?7) zGtggfKirwgs5vk4=}wQspXv{K!k z#P)ZxPR**-@W~LbRQS=s7WELB#QySn!d68_@_rqi!XX>P`ogcpzorMhed=)9_K;N! zEu$pcm98M?zF2BDXcDT>$#}HgfNbU|PX$>fFTLCE4;FivVkNc&*Qb?2H(|tNqRZdb zOWWYN#LCQ>?yU|9s#mtUGsJI$wEdRY$~z@_5e!n*XS3~SzfJNzEn0Lfx{V9J?@pDo zw#dsr`DWtL{)|Oq2#ZDUCvEh{03O-Xj2dMHz4_ChwNyXY{T)|Y+%A@36jBWdvvQRa&yFG?3yclAH`^> zx0ndL?Gp;t{EAsgUXGU&#Ll|f=}7x8#<(m*ox+cy9$U7c_r{JqJ5p$-{Jode^I+<` zU@7W^P92=3<{cj?jc*#iW9XWV-v@@EOqiR`4U-17(b6Rgk7Zv*F8mf^CT8;hhQ?Wn zpwTw1Ys&#fLPeF6RCzawHnz5?-J(R@>{nnDKVDlT!Z+D_QPo((v@kED$gIEc-Sl(D z##Z$aJVwIHb9aA6BJpG2*G*5ts*ds%7WMjwULxq(alV?kvgo3~v5V_fG-;vUzyPg(e;@Q&;--8G6BYf#h@vBb8i#T=f5X zG)Z0ksLg$JZSK37mFWDZ0x8FL@RYYVVOK2W)?Z5LP{j4(x0{KgE@xfxsApLtW=(N% zMzY}74_*+8pdsiX4-u}SUS${?x2JMqUojdjeeWxZ>Tmnl2<>m?v z8W|6l-_`}mJ}JNy4W(nZ>N$Bk;|^wos0t&Sj=MuSrihcLPdX2kTfV4cRRxMFe{}d{ zeZq$b8Uosex|T-|+!dtdhcq@X~9++rbI=yrMRXE1dQ0{2U>nL)P zC`V`Mxm7@#Gl42$12cCA^IpABm0fDFtZf&8PE1qq@t({hshwIW!DHu?9 zmX`R6a(y%t!0#-n5w&^bKYr6j#b0hd|6!hqUKs*Jr_iqw56Zg+?4z`Lz#h$}t+lTIf(rN2WQ z8|YmqE3-S~E*s0Hu-UJ*2pMJ=2a@QQM>?68G1JoskxG8KB9yFa!XGWK; zhLYYAW(k-&YM4Lx_RAicYvji2#_y8uz~Id9gX~iBA1Ya`zwd>;2naIX&a+hz7~6H+ zG`_Qf^;IE_ulk-!bTD{*~(US8s@Y$aI)Dp1OFH%{0$xE#!rPs1E_6#B%wz)7+M~X3S zzg|yTpElfKW926QV!iND!L;b^C}sc!`V`z?%`$V+I+HF;_{~xF78tocJ57(;D=WoC zMGy0yFKDJ;>2Rm5fp~5fBvO4h;tu-I`MFYP-K6=Lx@d@F^}#0Rv)_gy6Hy`@&qj++N(V)ZsEyYHR;l;lSLsZG?yr050of=L0{r%8uQ4aNx3p0u-fa6*4;0}kYda%Ic|L_qU8|4cWw^)~rfV=QP}r#inA?anvjA56HL~%q2n|%Nx-m;Mrnqx2NCfel?NdpD~dSrd>0t z8&1&FvyMes=RHOD95AIhA5S~N<+!&4qt_%h^AS`^r~S%Ho@yM;Dpc;y z#FWt$ zUo?Y#G_Yih*64a=I<(aFs>96gDJI3Chmu|^UQcj)v3Mw9f0eqj1Y-Mc7VB}{4BMvyU>#~W7;XxQh-2&VzbJbRCOTJElryaQ*sEk&cRiS~M`^tQuc z7W#YUpR56pnj$FT&vx}(S@)vF^7X=d2t_0!N)$e;`kGcZRr4-!*cm7)d1J_`K!N|L z8ylw6o2kaso)R6oiuQ<%t_1JKudg&;#xuh3tMQ)~z)#(-F`PF*jP@jpeZs&f&Gb0@ zz3g%gbb8fCW9rIAmsnDCv@KZ+`zrSfo+Sh2yj=Es-C)d6D0s6Zt@x-pXP=O4J6fPxz~6(;^LGHi3(REf0JtpgyTc!pU#Yd)L#n6Vo6-lKkY9;h4fBY$8!M zm!0G9MXm4n_@IAhZ6+hi9{v8od6~887EYeG(n|C1*b=nH8qVOF4$uuk+0#jO78TCg zPpsdR#Cqt<1+G=BHgWcCIP=r12CfB)pqL?rCvHPcH^~t)*jVmkT#+$eFnCS@eeBsb zNNa;UR*2XA0yc+it0{$a)t%VE1S_=W=kS6=Oe}>is8h*;p26R;B>sZy_QcyR5QHKQ z7ncrsMjX2o>L|m;4mXPf=t_j0THnbRJ3?q9JNs_4wCnX}%7Gy0y6)JnMn3o3eWBQfPP|z%ukD&iv}EB$Y-)iXw9Hd5i+9rCmoT?3PdpJ{ z3&}o6l4Ms(RtHyKQdcCE`0QZ|9_#GxHZVk2;^F#}Q(lV>iLptE+2M1liL{$l z|Fo-8NNZCXW?JKQ$M_kd*4|3&Cm)tQ=j4{y7fGW`DiTIKH-a>(rx@eg1aqo$55ntCTUy?$zNAU`O z?|G30Wq0k;#596->gw$}=FwM_krN6GhNaHQ(7)^YcIQk5NNgV^9xRxt?gvVT8#)h| zGK=qQ!Be zBI-yaJ9yCemU;s7n>kax-p&OUyjTcef-?i(%}2C5#&<%@h2UvNgS!x z>J&U{$@VyH2z)2Dy!3BgUU}5&`eyH=WPpmiB4ZbU$3~8!0_dGD#mI(H;7avid^+0- zyWjyE;kLA;mx)5Q2K*vN*2NJ=di&N9a^}YB#n?E@yv@?${Q5Hb}$f@ZtgM z!j3?N@S`Q~%0g#U$bTS?Bn3jVAOiI+^?HdN&2Ae#n$+KCznV68PDL6fOh%`Hvdb{q z0f2NTTWY6#{G`~#fG}mzr68mr7r`YX7s;b=n%+?vwl_2u9CG}CGKtR=FU*dmsiWof zjoU;5XTAXckYSly%8IQrWrT)bJh1EAQ%&6MUI)eam)K@D+Y>9+XH^!41hGest|e@x z{z>&$0`n7xY|5>LCth9b)CGBWQ=4Xw=?1IF-)Eq230q6&6N)nSj|9g){q@)UNsqsw z5E9}eSgdKF&C~hu=;7g^<1RXb+8Am)?MaGT7{uo$R?3X<^^Wz=ws1~vy%IibLqW34 z&TN0;En@*Epu7v=_QqT$dyHb4NQ9~+FV#I^Ow znfN|p<(!~Ywp6uu2_=S-c~r>4njrz8GXDm<-l81*4!|muYrgee@3~HdMA$?eMoU0Tf<;gC-KN6pDCMzj1Jyvh5x1FmVB;9I zY0=FS;N!;C{&L_8--#0qk->F-V$aAgZBur8$ z83@NsFGtw7=O9lJ=g#^SVO&{*rs$5^11*&{%2`>RNN9M&eNR* zDgg3$3C(3t;Tk8`zK>q4K02Hxd%o)T54Gj@hn``vL1|ae>mlgjG73!tx#RcgU(u=_ zPv~&(B^E`IE&z8`cFPwPm!mVD1wZ>kdVHX-FLH9pr98r!r~uOx>KJqJ1xeLiUUytO znizTGy*`C8VDI1AVXo=p(*6T<}=m-rxA}@Mifg(BaYpLScZyU{Z6DI7=ja1N8OwL;pVx zUj`_Y%_&U*=M?zl0edg7mgsnv5FbT=w}@nM{zEBv0*va(bwQj>5j&~?@I*%6;$+Qd z0jBid#jF54_-|2Qbr28mu78W-kA22dMs+sUy5GeBZ?|s05*~l-KEEjX*pWaZxwJz- zr>g9Yyy(1kTXuET#2dO!kZ)!nK_@puL2w|oYUDqr=k+WQY}wYezq8f_xB{BgpH3xZ z#5?Qgl)QK{=(&gK(l(0^Zxvnph3wJL?b#~8c{CS>Rr(sa$Rj?%lKS8TDEEbOCm!)I)qgzA#S=g zUSwLJ*TpEKQ-AEPt{ZO^q!xCss@&=|Y>=&}293ksV#)RrK=jz1&(D1*4BWM~jAg1Qk{Q9AHk4(( z;&YiHN8|HcH~UxF;w}s`XW;E1{e}_^{B<-vDuyQ_PB2s7N1#%oN_NsrdU^j{j2PvOCG7K49(RbmE?{kH}p{w1g-O=tc%bpUPZ zPdbQHeZ!I#D6*vuu>t5t=_Y?aBwZ=dfG`OpnAW-hegc5d>*&GIj>SkyYASnANdPbt z+XYN3U#b$ZE<>lItM(RiNb7e2v|`|8jf?NlBp5zD88kyNK1NY&qua4ZU6TriEh_Dz z;eGlp3hoQ}()?mwARpIQmol(#WU&Ak$)|*`Cu|7f?o+~^B;xh(D*&xQhbHcutnl(A zC%*VWQWy1=X6>%+XoVwS3}uw0QVCJh+tpHR{L((js4^3v4Fv5>?)A44K8OQ|f)a%W z*g+DqsA9pCR}L^ky!ba?05qbo#S<6iiPhAM^zhqbM%qP2Er%w}^wJStmrf$U91y}; z^9_=49CZ+ybQwgATRNM#WQyEe8^nN{$tR(VFa{9O1XD~6PX>tqp^E#WEH2Fadx(F_ z0-Nag{J*gaBiUwlH7*|zNCI^}_Ej!Ar7RksKC#UYAQKB-c*==Oqd;{>m_+|FoC|jW zr26>nAM~wG?0xn=j3p+ihxKjih96bHZ%gZZACdkzTc)k@A>wcPCP?9JXlKBf>k9N9% z4GI&rjKMxWcof4xU|EbNPAYy9GF8Jv)m~Dz^SC>NM0pQ z&0H&O_#o0kQkYC^UAfsJC=7b+SOozi9r?T`o3bh*>?1%8Y&QC{%DRAGMUm?6<8=eK zdaeBomf~^y{>E&M&bKu9SwU}fR|d6aSOnnp66eyB5$?LxNv z8(fa+1~^k|xe|X42w)Xp!UmW`xlJZfxaz4GR8RjN;NLPR{uWkIAi-a1_{HdZZCt-L z&VZ=M0m;orR*ev6VT!=Q;-1SH{Br}S$CEBl;aGL=LxDwQ42JwUIRd;A^c1!p&wMC} zE5&|;GPotH=r^u4p^OLO-zkpA6u3g`E-0%Uvbo)G{y+_s!T-0Xz?aq)tq-`5Wt)SR zZ{wf6rFVYhFw?4lB|Mj{wTjFyH57qtsp@d>pRBi#P?*6RBspAIa5g7L3;-`^zyoj- zUi)<`0J08vvI>BMpfu=;3JQRO9w#-PxqdV5@xMuo5CA?Mo7gkDr^F9e5Y#?1f6(D_ zEcm*GZ5Zu}Yv6=Hn9bR~0&%=C^5ZpW7eMGZnr$ zz-C=K74d*frg+3zcNcVt)y9gjNI7s7eTE1p)6P^G_Cs*+%leay+FS{{YI-U-G$O#q zr<`RURLJ)v87`Wh0T+EnVc8)F*dv%VR32A{_+&xN44UZ?5~1aK7S=5;F^GPAi$T=) z$bpik4IRa9~x?3&Bd)qZE_?@U|8_xA>jUQ z^aot(`$*6XxN>7Lwx3a*Q&cEXgy`x|N<5R#6uEk(H^o3V-2xz~uP3qe8plz$nKUfX z$El|-fI0)q+dUMfDzcj zRR5_#+RQ^-TV+L3T=e6E?;$E@#R5PCu{yUR$(_qlCw3L1^HHeKdFfGkXISg@nLu5# zS)uBk79{8m_WHKnm?j_-Ro?f>JC%gRYI*=xLwXZMUAoyktQa%8oq+Z;+-j1h zPT|v6F?}0NqU3sicUD?L=feedDUnl?vMnfvtrAB7As}yQTc|%Ak1`Hs$Io?Wy_<23 z<+&0+wt(2Yemz{4IB-Zb37Z5Df^H#Q`{d9BKuZ%rSkPH#t)1G$c3l}f1Q&*X%A-Y%~mmqNF~i1Pf@oZ*+QOK@vS5X?{h^e z{z)bsc7di?ZaK}qD?J_@HKvjY#8-J58U!8|P641ovc~b2$ikNgF}KVVG1d~dsBd(MKmFP6 z)TiI4+-c61zrAm6lrBCffTbS0J~)9H|~7WcF)1JDoBwcG%_r20#aR>=lS zzzQ&O)Vd~U!lqmVufSN_avu8Cj(l2SdId^VVJsVp%O)bgu9@GrX32A_e9}-f-m;)Y zu(|dAo42H4){H9yVcafvtO8m4m5n-pFm;u~2?JwtVQUI+8* zKr=<#bQkIA#U-*kX~R-XeWLuTWSb=pQ4;6(fmFHt9YNch3|r99X{`kzll=fZ%6Qsf zr%Chtr)a6P{;FxBEFXY3Woa3%A=75+Ipl-2f|@f+YsNG(X@X!a4@iL* zGb8&HJ(AY{d(AjAaKnH)vzw;f^=k)k!U@2aMqcAX7-U_(^(++&xLj4P-kFXKfIkl% zX<*sL;&XN4b_2H!`XZ8-dWv?UGoS;T`JjiMhPCI7`%<=M7!n4{L+@1X;^CWhzEoA< zYzrI0H|LgVwMr5E;k^|4+KVGR07#mA{KN9_J>}Ha&IkA{Ei=3r3&z5Smw5EF^dtjz za*bDZ9*3@kLS@4NYHP10Y9?N9(;MOH-wEFu(RA0|uK+9`+Js!nE{PFvWTVdA5~e_x z?n}FC@Zg%kA2rufhYm)y-I;bs+|$$PT6-L}g{5)%=hv(d4{W>jKY5!*bMe_9i}eeU zVzL93ZklWD_|8mXB7lNjC?Vn!tG1`-Iqu!Uq(s!mFsx82jRaK70b|W<+?HWVlO1`5 zJ>mF7iS3>3=av2KI`KkpWBAfJg&LSAzGa_vm{IEHW6pt?WLmWT5=@hywZz%C zkq)p3DUUvyiA9u5Fu@-5>3z+kpEgU!Z$TnJEX<=ZV=&Y>56Fy;%im8^YZ~?{8qb=^ zrE`5f(DW&s7Zl7}T4QG51niQxqt7PR9ynZEj)DS626euM2EuUfp7p!YHtwSSkDFh& zOF^&@T=%aR#~wdfF*tjHanM+}bLHGSw+}%;XB4OWr5ox^3$RYrqUFvc?6UElhW5=u z&_ha_eO&yT7i^WF`9k#$OmjOVTxtd~Hi5?)b?U8E4LoeG&vc0Jk~OMH4*sC6F8pqwD{x^sXTJG2Ht zR<0}BEJ6F%7>(+J$Ls?}*%iEtk!pva?NmvujM~<$-tDQQNno&L3upHPjzM*yHpTdD zFiWtTc=cvsUK*fJ^2OUXv7=i>mgKSLi}*KMvG^R!R?9RAhGYUe*2A+_w8k!F5Hz{` zok7opjk0S27@Ttr`;hqk3BaA@Jv=-cPt-mmT{!f%^ER7uDFmspk3H7fZRXa%h$xAp zbt%ZLtW{v;=Mi|RBDX=P;JBuJBzl z3&)W78-`nsBQp)k=jJOplm{S4O-{8^T+%thqns7{zKmY?@FZX2aK0FF2A49D&w64{ zDjQ1MpP(~gpvY9|$>PI-EsNCTYI@H$ArOLl*uMqf?d(P0c=fnO1(aWKYFRzw2d?i} zW(Zm`2Ts@D;+~cTIVz`m{Fw(ywD>FU{e&te&Y^+XDhO}(8+U4(Ig)pDso(buIoyI)fH4kYvbgZGU5Gd1n6vPpe} z=kJVrucMW`%5H4lN>~Y`Jn{s*(?8kb!FGd$B3q(|{ceWWZpP$61_&1H_?mxEDaUGX z*k>`1`R?`h0(`6zD;EHhQFjn9A-X^u)U^s2Z5OIUE1&_3*G3qf8rms1WEJ{{B6IjB zbxm>yt*H@RA$zH$nNvlhu=%okpjyY~#PcYq65#i)Z{&H2iA}L9$zZwOFp#e%DBhWP zwfjGL90+Zx=Ny)!=!gmuN(a!anAqx1W{dAHPg!88tUMiKAp1f4GVU7*Z*;460YGW4 zK?~cu^I60;{>>_XQsLoS61GYl?XLq~1J{T{n;06tp_@rvv$F=v~9CL z-+F)}-fbDVzr&zy#I-D&vmJrsU4I(vJy^i(Ur&m)6a1%xU;ts%%#g*MGMIf1YA;Pq z#4p@ooovt__-qi*fjjS)lmqmsuP=5JcRW8c0a)w5zGM5yZG2gywr%1k1pJecRD76w I-{|H40E=fEiU0rr diff --git a/tests/testthat/_snaps/autoplot-methods/autoplot-halfmoon-calibration.svg b/tests/testthat/_snaps/autoplot-methods/autoplot-halfmoon-calibration.svg index b856057..c1980ca 100644 --- a/tests/testthat/_snaps/autoplot-methods/autoplot-halfmoon-calibration.svg +++ b/tests/testthat/_snaps/autoplot-methods/autoplot-halfmoon-calibration.svg @@ -18,6 +18,7 @@ + diff --git a/tests/testthat/_snaps/autoplot-methods/autoplot-halfmoon-qq.svg b/tests/testthat/_snaps/autoplot-methods/autoplot-halfmoon-qq.svg index d769a35..411b2c8 100644 --- a/tests/testthat/_snaps/autoplot-methods/autoplot-halfmoon-qq.svg +++ b/tests/testthat/_snaps/autoplot-methods/autoplot-halfmoon-qq.svg @@ -25,6 +25,7 @@ + diff --git a/tests/testthat/_snaps/autoplot-methods/plot-halfmoon-calibration.svg b/tests/testthat/_snaps/autoplot-methods/plot-halfmoon-calibration.svg index 67ff99e..f0d37d2 100644 --- a/tests/testthat/_snaps/autoplot-methods/plot-halfmoon-calibration.svg +++ b/tests/testthat/_snaps/autoplot-methods/plot-halfmoon-calibration.svg @@ -18,6 +18,7 @@ + diff --git a/tests/testthat/_snaps/autoplot-methods/plot-halfmoon-qq.svg b/tests/testthat/_snaps/autoplot-methods/plot-halfmoon-qq.svg index 11da3b6..1538f3f 100644 --- a/tests/testthat/_snaps/autoplot-methods/plot-halfmoon-qq.svg +++ b/tests/testthat/_snaps/autoplot-methods/plot-halfmoon-qq.svg @@ -25,6 +25,7 @@ + diff --git a/tests/testthat/_snaps/geom_mirrored_density/fill-with-theme.svg b/tests/testthat/_snaps/geom_mirrored_density/fill-with-theme.svg index 7017d06..0d1805b 100644 --- a/tests/testthat/_snaps/geom_mirrored_density/fill-with-theme.svg +++ b/tests/testthat/_snaps/geom_mirrored_density/fill-with-theme.svg @@ -18,6 +18,7 @@ + diff --git a/tests/testthat/_snaps/geom_mirrored_histogram/layered-weighted-and-unweighted.svg b/tests/testthat/_snaps/geom_mirrored_histogram/layered-weighted-and-unweighted.svg index 65e2784..9e8e608 100644 --- a/tests/testthat/_snaps/geom_mirrored_histogram/layered-weighted-and-unweighted.svg +++ b/tests/testthat/_snaps/geom_mirrored_histogram/layered-weighted-and-unweighted.svg @@ -27,229 +27,227 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -100 -50 -0 -50 -100 - - - - - - - - - - -0.0 -0.2 -0.4 -0.6 -0.8 +100 +50 +0 +50 +100 + + + + + + + + + +0.2 +0.4 +0.6 +0.8 .fitted count diff --git a/tests/testthat/_snaps/geom_qq2/geom-qq2-basic.svg b/tests/testthat/_snaps/geom_qq2/geom-qq2-basic.svg index b268a9a..303e465 100644 --- a/tests/testthat/_snaps/geom_qq2/geom-qq2-basic.svg +++ b/tests/testthat/_snaps/geom_qq2/geom-qq2-basic.svg @@ -126,7 +126,7 @@ - + diff --git a/tests/testthat/_snaps/geom_qq2/geom-qq2-custom-quantiles.svg b/tests/testthat/_snaps/geom_qq2/geom-qq2-custom-quantiles.svg index 9a766cc..83a2cb1 100644 --- a/tests/testthat/_snaps/geom_qq2/geom-qq2-custom-quantiles.svg +++ b/tests/testthat/_snaps/geom_qq2/geom-qq2-custom-quantiles.svg @@ -32,7 +32,7 @@ - + diff --git a/tests/testthat/_snaps/geom_qq2/geom-qq2-multiple-weights.svg b/tests/testthat/_snaps/geom_qq2/geom-qq2-multiple-weights.svg index 0a42fbb..ff7b6b0 100644 --- a/tests/testthat/_snaps/geom_qq2/geom-qq2-multiple-weights.svg +++ b/tests/testthat/_snaps/geom_qq2/geom-qq2-multiple-weights.svg @@ -225,7 +225,7 @@ - + diff --git a/tests/testthat/_snaps/geom_qq2/geom-qq2-weighted.svg b/tests/testthat/_snaps/geom_qq2/geom-qq2-weighted.svg index 3e05b8c..c27a030 100644 --- a/tests/testthat/_snaps/geom_qq2/geom-qq2-weighted.svg +++ b/tests/testthat/_snaps/geom_qq2/geom-qq2-weighted.svg @@ -126,7 +126,7 @@ - + diff --git a/tests/testthat/_snaps/plot_balance/balance-plot-categorical-ks-only.svg b/tests/testthat/_snaps/plot_balance/balance-plot-categorical-ks-only.svg index 17cf72f..1552ff9 100644 --- a/tests/testthat/_snaps/plot_balance/balance-plot-categorical-ks-only.svg +++ b/tests/testthat/_snaps/plot_balance/balance-plot-categorical-ks-only.svg @@ -21,100 +21,100 @@ - - + + - - - - - - - - - - - + + + + + + + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + + - - + + - - -daily + + +daily - - + + - - -lt_12_per_year + + +lt_12_per_year @@ -139,73 +139,72 @@ 2_3_per_week - - - -0.08 -0.12 -0.16 - - - - -0.05 -0.10 -0.15 -0.20 - - - -0.1 -0.2 -0.3 - - - - - -0.05 -0.10 -0.15 -0.20 -0.25 -age -smokeintensity -wt71 - - - -age -smokeintensity -wt71 - - - -age -smokeintensity -wt71 - - - -age -smokeintensity -wt71 - - - -balance metric -variable - -method - - - - - - -observed -w_cat_ate + + + +0.08 +0.12 +0.16 + + + + +0.05 +0.10 +0.15 +0.20 + + + +0.1 +0.2 +0.3 + + + + + +0.05 +0.10 +0.15 +0.20 +0.25 +age +smokeintensity +wt71 + + + +age +smokeintensity +wt71 + + + +age +smokeintensity +wt71 + + + +age +smokeintensity +wt71 + + + +balance metric +variable + +method + + + + + + +observed +w_cat_ate balance-plot-categorical-ks-only -smd values shown as absolute values diff --git a/tests/testthat/_snaps/plot_balance/balance-plot-variance-ratio.svg b/tests/testthat/_snaps/plot_balance/balance-plot-variance-ratio.svg index 5bfd222..247402d 100644 --- a/tests/testthat/_snaps/plot_balance/balance-plot-variance-ratio.svg +++ b/tests/testthat/_snaps/plot_balance/balance-plot-variance-ratio.svg @@ -21,62 +21,61 @@ - - + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + -age -education1 -education2 -education3 -education4 -education5 - - - - - - - - - - -0.4 -0.8 -1.2 -1.6 -balance metric -variable - -method - - - - - - -observed -w_ate +age +education1 +education2 +education3 +education4 +education5 + + + + + + + + + + +0.4 +0.8 +1.2 +1.6 +balance metric +variable + +method + + + + + + +observed +w_ate balance-plot-variance-ratio -smd values shown as absolute values diff --git a/tests/testthat/_snaps/plot_mirror_distributions/basic-histogram.svg b/tests/testthat/_snaps/plot_mirror_distributions/basic-histogram.svg index e8c1c4a..afd466c 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/basic-histogram.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/basic-histogram.svg @@ -27,88 +27,81 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -120 -80 -40 -0 -40 - - - - - - - - - - -30 -40 -50 -60 -70 +100 +50 +0 + + + + + + + + +30 +40 +50 +60 +70 age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-histogram.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-histogram.svg index 6fc676d..d6d9cb6 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-histogram.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-exposure-histogram.svg @@ -27,65 +27,67 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -96,65 +98,67 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -165,65 +169,67 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -234,65 +240,67 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -339,42 +347,46 @@ 2_3_per_week vs none - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -25 -0 -25 -50 - - - - -25 -0 -25 -50 - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +20 +0 +20 +40 +60 + + + + + +20 +0 +20 +40 +60 + + + + + age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/categorical-with-weights.svg b/tests/testthat/_snaps/plot_mirror_distributions/categorical-with-weights.svg index 8e70533..b569a82 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/categorical-with-weights.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/categorical-with-weights.svg @@ -27,60 +27,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -91,60 +97,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -155,60 +167,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -219,60 +237,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -283,60 +307,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -347,60 +377,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -411,60 +447,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -475,60 +517,66 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -597,46 +645,70 @@ lt_12_per_year vs none - - - - -40 -80 -120 -160 - - - - -40 -80 -120 -160 -200 -0 -200 - - - -200 -0 -200 - - - -200 -0 -200 - - - -200 -0 -200 - - - + + + + +60 +90 +120 +150 + + + + +60 +90 +120 +150 +200 +100 +0 +100 +200 +300 + + + + + + +200 +100 +0 +100 +200 +300 + + + + + + +200 +100 +0 +100 +200 +300 + + + + + + +200 +100 +0 +100 +200 +300 + + + + + + wt71 Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/custom-aesthetics.svg b/tests/testthat/_snaps/plot_mirror_distributions/custom-aesthetics.svg index f8dfd8c..4bffbbd 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/custom-aesthetics.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/custom-aesthetics.svg @@ -27,88 +27,81 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -120 -80 -40 -0 -40 - - - - - - - - - - -30 -40 -50 -60 -70 +100 +50 +0 + + + + + + + + +30 +40 +50 +60 +70 age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/fixed-facet-scales-default.svg b/tests/testthat/_snaps/plot_mirror_distributions/fixed-facet-scales-default.svg index 0fdec71..8a68ed7 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/fixed-facet-scales-default.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/fixed-facet-scales-default.svg @@ -27,64 +27,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -95,64 +95,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -177,32 +177,32 @@ w_ate - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -100 -0 -100 - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/free-facet-scales.svg b/tests/testthat/_snaps/plot_mirror_distributions/free-facet-scales.svg index cae3eed..5b25681 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/free-facet-scales.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/free-facet-scales.svg @@ -27,66 +27,63 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -97,64 +94,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -165,64 +162,65 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -258,58 +256,56 @@ w_att - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -25 -0 -25 - - - -100 -0 -100 - - - -120 -80 -40 -0 -40 - - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +40 +20 +0 +20 + + + + +100 +0 +100 + + + +100 +50 +0 + + + age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/free-y-facet-scales.svg b/tests/testthat/_snaps/plot_mirror_distributions/free-y-facet-scales.svg index 02ffbef..0882703 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/free-y-facet-scales.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/free-y-facet-scales.svg @@ -27,66 +27,63 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -97,64 +94,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -179,42 +176,38 @@ w_ate - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -100 -0 -100 - - - -120 -80 -40 -0 -40 - - - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + +100 +50 +0 + + + age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/mirror-x-axis.svg b/tests/testthat/_snaps/plot_mirror_distributions/mirror-x-axis.svg index aeaed2a..65dfe05 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/mirror-x-axis.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/mirror-x-axis.svg @@ -27,88 +27,81 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -30 -40 -50 -60 -70 - - - - - - - - - - -120 -80 -40 -0 -40 +30 +40 +50 +60 +70 + + + + + + + + +100 +50 +0 Count age diff --git a/tests/testthat/_snaps/plot_mirror_distributions/multiple-weights.svg b/tests/testthat/_snaps/plot_mirror_distributions/multiple-weights.svg index 83ce259..47a5574 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/multiple-weights.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/multiple-weights.svg @@ -27,64 +27,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -95,64 +95,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -163,64 +163,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -256,42 +256,42 @@ w_att - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -100 -0 -100 - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/no-unweighted.svg b/tests/testthat/_snaps/plot_mirror_distributions/no-unweighted.svg index 4731bdc..257cde3 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/no-unweighted.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/no-unweighted.svg @@ -27,64 +27,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -98,22 +98,22 @@ w_ate - - - - - -30 -40 -50 -60 -70 -100 -0 -100 - - - + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + age Count diff --git a/tests/testthat/_snaps/plot_mirror_distributions/weighted-histogram-default.svg b/tests/testthat/_snaps/plot_mirror_distributions/weighted-histogram-default.svg index e956643..b2b6156 100644 --- a/tests/testthat/_snaps/plot_mirror_distributions/weighted-histogram-default.svg +++ b/tests/testthat/_snaps/plot_mirror_distributions/weighted-histogram-default.svg @@ -27,64 +27,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -95,64 +95,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -177,32 +177,32 @@ w_ate - - - - - -30 -40 -50 -60 -70 - - - - - -30 -40 -50 -60 -70 -100 -0 -100 - - - + + + + + +30 +40 +50 +60 +70 + + + + + +30 +40 +50 +60 +70 +100 +0 +100 + + + age Count diff --git a/tests/testthat/_snaps/plot_qq/basic-qq-plot.svg b/tests/testthat/_snaps/plot_qq/basic-qq-plot.svg index f1fbf76..6f82717 100644 --- a/tests/testthat/_snaps/plot_qq/basic-qq-plot.svg +++ b/tests/testthat/_snaps/plot_qq/basic-qq-plot.svg @@ -126,7 +126,7 @@ - + diff --git a/tests/testthat/_snaps/plot_qq/qq-plot-multiple-weights.svg b/tests/testthat/_snaps/plot_qq/qq-plot-multiple-weights.svg index 7dc3405..09b1415 100644 --- a/tests/testthat/_snaps/plot_qq/qq-plot-multiple-weights.svg +++ b/tests/testthat/_snaps/plot_qq/qq-plot-multiple-weights.svg @@ -324,7 +324,7 @@ - + diff --git a/tests/testthat/_snaps/plot_qq/qq-plot-no-observed.svg b/tests/testthat/_snaps/plot_qq/qq-plot-no-observed.svg index f86cdc5..ddab31f 100644 --- a/tests/testthat/_snaps/plot_qq/qq-plot-no-observed.svg +++ b/tests/testthat/_snaps/plot_qq/qq-plot-no-observed.svg @@ -126,7 +126,7 @@ - + diff --git a/tests/testthat/_snaps/plot_qq/qq-plot-propensity-score.svg b/tests/testthat/_snaps/plot_qq/qq-plot-propensity-score.svg index f462ce8..387298a 100644 --- a/tests/testthat/_snaps/plot_qq/qq-plot-propensity-score.svg +++ b/tests/testthat/_snaps/plot_qq/qq-plot-propensity-score.svg @@ -225,7 +225,7 @@ - + diff --git a/tests/testthat/_snaps/plot_qq/qq-plot-with-weight.svg b/tests/testthat/_snaps/plot_qq/qq-plot-with-weight.svg index b0b547c..ae9a860 100644 --- a/tests/testthat/_snaps/plot_qq/qq-plot-with-weight.svg +++ b/tests/testthat/_snaps/plot_qq/qq-plot-with-weight.svg @@ -225,7 +225,7 @@ - + diff --git a/tests/testthat/test-plot_mirror_distributions.R b/tests/testthat/test-plot_mirror_distributions.R index 4891161..118a4bc 100644 --- a/tests/testthat/test-plot_mirror_distributions.R +++ b/tests/testthat/test-plot_mirror_distributions.R @@ -224,7 +224,9 @@ test_that("plot_mirror_distributions produces correct plot structure", { expect_length(built$data, 1) # Check that y-axis uses absolute values - y_labels <- built$layout$panel_params[[1]]$y$get_labels() + y_labels <- built$layout$panel_params[[1]]$y$get_labels() |> + na.omit() |> + as.numeric() expect_true(all(as.numeric(y_labels) >= 0)) }) diff --git a/tests/testthat/test-plot_roc.R b/tests/testthat/test-plot_roc.R index 5afa0e5..e3dce4b 100644 --- a/tests/testthat/test-plot_roc.R +++ b/tests/testthat/test-plot_roc.R @@ -170,9 +170,6 @@ test_that("plot functions produce expected output structure", { expect_equal(p_auc$labels$x, "auc") expect_equal(p_auc$labels$y, "method") - - # Check coordinate system for ROC plot - expect_s3_class(p_roc$coordinates, "CoordFixed") }) # vdiffr tests From e2bd7f9a2c8e3a4886b5bb2a517c4cd5ddad0730 Mon Sep 17 00:00:00 2001 From: Malcolm Barrett Date: Tue, 4 Nov 2025 10:42:56 -0500 Subject: [PATCH 10/14] air format --- data-raw/nhefs_weights.R | 48 +++++++++---------- .../testthat/test-plot_mirror_distributions.R | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/data-raw/nhefs_weights.R b/data-raw/nhefs_weights.R index 4888fa2..1504668 100644 --- a/data-raw/nhefs_weights.R +++ b/data-raw/nhefs_weights.R @@ -8,18 +8,18 @@ library(propensity) propensity_model <- glm( qsmk ~ sex + - race + - age + - I(age^2) + - education + - smokeintensity + - I(smokeintensity^2) + - smokeyrs + - I(smokeyrs^2) + - exercise + - active + - wt71 + - I(wt71^2), + race + + age + + I(age^2) + + education + + smokeintensity + + I(smokeintensity^2) + + smokeyrs + + I(smokeyrs^2) + + exercise + + active + + wt71 + + I(wt71^2), family = binomial(), data = nhefs_complete ) @@ -67,18 +67,18 @@ nhefs_for_model <- nhefs_with_cat %>% cat_ps_model <- multinom( alcoholfreq_cat ~ sex + - race + - age + - I(age^2) + - education + - smokeintensity + - I(smokeintensity^2) + - smokeyrs + - I(smokeyrs^2) + - exercise + - active + - wt71 + - I(wt71^2), + race + + age + + I(age^2) + + education + + smokeintensity + + I(smokeintensity^2) + + smokeyrs + + I(smokeyrs^2) + + exercise + + active + + wt71 + + I(wt71^2), data = nhefs_for_model, trace = FALSE ) diff --git a/tests/testthat/test-plot_mirror_distributions.R b/tests/testthat/test-plot_mirror_distributions.R index 118a4bc..cfdff12 100644 --- a/tests/testthat/test-plot_mirror_distributions.R +++ b/tests/testthat/test-plot_mirror_distributions.R @@ -225,7 +225,7 @@ test_that("plot_mirror_distributions produces correct plot structure", { # Check that y-axis uses absolute values y_labels <- built$layout$panel_params[[1]]$y$get_labels() |> - na.omit() |> + na.omit() |> as.numeric() expect_true(all(as.numeric(y_labels) >= 0)) }) From 0da0b51c179b72bf156d785269455547f6adaa96 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Nov 2025 15:43:41 +0000 Subject: [PATCH 11/14] Initial plan From 7cadf6f7a311e9180bac273189df839d7d106043 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Nov 2025 15:44:24 +0000 Subject: [PATCH 12/14] Initial plan From 8e7c660fed937f878f9b6b3f1938faa1845f4342 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Nov 2025 15:46:17 +0000 Subject: [PATCH 13/14] Remove redundant as.numeric() conversion in test Co-authored-by: malcolmbarrett <23123711+malcolmbarrett@users.noreply.github.com> --- tests/testthat/test-plot_mirror_distributions.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-plot_mirror_distributions.R b/tests/testthat/test-plot_mirror_distributions.R index cfdff12..4bac269 100644 --- a/tests/testthat/test-plot_mirror_distributions.R +++ b/tests/testthat/test-plot_mirror_distributions.R @@ -227,7 +227,7 @@ test_that("plot_mirror_distributions produces correct plot structure", { y_labels <- built$layout$panel_params[[1]]$y$get_labels() |> na.omit() |> as.numeric() - expect_true(all(as.numeric(y_labels) >= 0)) + expect_true(all(y_labels >= 0)) }) test_that("plot_mirror_distributions works with faceting", { From 0f0f3769358363c3f837519e1141c62d85251bad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 4 Nov 2025 15:46:43 +0000 Subject: [PATCH 14/14] Use stats::na.omit() for consistency Co-authored-by: malcolmbarrett <23123711+malcolmbarrett@users.noreply.github.com> --- tests/testthat/test-plot_mirror_distributions.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-plot_mirror_distributions.R b/tests/testthat/test-plot_mirror_distributions.R index cfdff12..fddc766 100644 --- a/tests/testthat/test-plot_mirror_distributions.R +++ b/tests/testthat/test-plot_mirror_distributions.R @@ -225,7 +225,7 @@ test_that("plot_mirror_distributions produces correct plot structure", { # Check that y-axis uses absolute values y_labels <- built$layout$panel_params[[1]]$y$get_labels() |> - na.omit() |> + stats::na.omit() |> as.numeric() expect_true(all(as.numeric(y_labels) >= 0)) })