From 399c6341bf90ad86717f9b4339afd65c13fc4d46 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 9 Aug 2025 15:02:56 +0000 Subject: [PATCH 1/7] Initial plan From 532e51b1d47554d7d4491c19821a99c2a15fe33b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 9 Aug 2025 15:08:06 +0000 Subject: [PATCH 2/7] Initial plan: Add variable pre-filtering mechanism to br_run and br_pipeline Co-authored-by: ShixiangWang <25057508+ShixiangWang@users.noreply.github.com> --- tests/testthat/Rplots.pdf | Bin 0 -> 138842 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/testthat/Rplots.pdf diff --git a/tests/testthat/Rplots.pdf b/tests/testthat/Rplots.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4a2f17e64159fffeb966737486f3d8ccda0e9017 GIT binary patch literal 138842 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 nVn-&hH=#r$GMPev;9 Date: Sat, 9 Aug 2025 15:13:51 +0000 Subject: [PATCH 3/7] Implement variable pre-filtering mechanism for br_run and br_pipeline Co-authored-by: ShixiangWang <25057508+ShixiangWang@users.noreply.github.com> --- R/02-pipeline.R | 86 +++++++++++++++++- R/98-utils.R | 97 ++++++++++++++++++++ tests/testthat/Rplots.pdf | Bin 138842 -> 138842 bytes tests/testthat/test-filter-variables.R | 118 +++++++++++++++++++++++++ 4 files changed, 298 insertions(+), 3 deletions(-) create mode 100644 tests/testthat/test-filter-variables.R diff --git a/R/02-pipeline.R b/R/02-pipeline.R index 3fb5702..65d5cb3 100644 --- a/R/02-pipeline.R +++ b/R/02-pipeline.R @@ -55,6 +55,10 @@ #' For logistic, and Cox-PH regressions models, `exponentiate` is set to `TRUE` at default. #' @param model_args A list of arguments passed to `br_set_model()`. #' @param run_args A list of arguments passed to `br_run()`. +#' @param filter_x Logical, whether to enable pre-filtering of focal variables. Default is `FALSE`. +#' @param filter_na_prop Numeric, maximum proportion of NA values allowed for a variable. Default is `0.8`. +#' @param filter_sd_min Numeric, minimum standard deviation required for a variable. Default is `1e-6`. +#' @param filter_var_min Numeric, minimum variance required for a variable. Default is `1e-6`. #' @examples #' library(bregr) #' # 1. Pipeline ------------------------- @@ -123,7 +127,11 @@ br_pipeline <- function( group_by = NULL, n_workers = 1L, run_parallel = lifecycle::deprecated(), model_args = list(), - run_args = list()) { + run_args = list(), + filter_x = FALSE, + filter_na_prop = 0.8, + filter_sd_min = 1e-6, + filter_var_min = 1e-6) { if (lifecycle::is_present(run_parallel)) { lifecycle::deprecate_warn("1.1.0", "bregr::br_run(run_parallel = )", "bregr::br_run(n_workers = )") n_workers <- run_parallel @@ -134,7 +142,10 @@ br_pipeline <- function( br_set_x(x) |> br_set_x2(x2) |> br_set_model(method = method, !!!model_args) |> - br_run(group_by = group_by, n_workers = n_workers, !!!run_args) + br_run(group_by = group_by, n_workers = n_workers, + filter_x = filter_x, filter_na_prop = filter_na_prop, + filter_sd_min = filter_sd_min, filter_var_min = filter_var_min, + !!!run_args) } #' @describeIn pipeline Set dependent variables for model construction. @@ -272,10 +283,18 @@ br_set_model <- function(obj, method, ...) { } #' @describeIn pipeline Run the regression analysis in batch. +#' @param filter_x Logical, whether to enable pre-filtering of focal variables. Default is `FALSE`. +#' @param filter_na_prop Numeric, maximum proportion of NA values allowed for a variable. Default is `0.8`. +#' @param filter_sd_min Numeric, minimum standard deviation required for a variable. Default is `1e-6`. +#' @param filter_var_min Numeric, minimum variance required for a variable. Default is `1e-6`. #' @export br_run <- function(obj, ..., group_by = NULL, n_workers = 1L, - run_parallel = lifecycle::deprecated()) { + run_parallel = lifecycle::deprecated(), + filter_x = FALSE, + filter_na_prop = 0.8, + filter_sd_min = 1e-6, + filter_var_min = 1e-6) { assert_breg_obj(obj) assert_character(group_by, allow_na = FALSE, allow_null = TRUE) on.exit(invisible(gc())) @@ -306,6 +325,67 @@ br_run <- function(obj, ..., ) } + # Apply variable filtering if enabled + original_x <- obj@x + if (filter_x && length(obj@x) > 0) { + assert_logical(filter_x, allow_na = FALSE) + assert_number_decimal(filter_na_prop, min = 0, max = 1) + assert_number_decimal(filter_sd_min, min = 0) + assert_number_decimal(filter_var_min, min = 0) + + filter_result <- filter_variables_x( + obj@data, obj@x, + filter_na_prop = filter_na_prop, + filter_sd_min = filter_sd_min, + filter_var_min = filter_var_min + ) + + obj@x <- filter_result$filtered_x + + # Inform user about filtering results + if (filter_result$filter_summary$filtered > 0) { + cli::cli_inform( + "Pre-filtering removed {filter_result$filter_summary$filtered} out of {filter_result$filter_summary$total} focal variables ({round(filter_result$filter_summary$prop_filtered * 100, 1)}%)" + ) + if (length(filter_result$filtered_out) <= 10) { + cli::cli_inform("Filtered variables: {.val {filter_result$filtered_out}}") + } else { + cli::cli_inform("Filtered variables (showing first 10): {.val {filter_result$filtered_out[1:10]}} ...") + } + } else { + cli::cli_inform("Pre-filtering: no variables were filtered out") + } + + # Update models to reflect filtered variables + if (length(obj@x) > 0) { + config <- br_get_config(obj) + + # Get the proper method configuration + if (!rlang::is_list(config$method)) { + method_config <- br_avail_method_config(config$method) + } else { + method_config <- config$method + } + + models <- gen_template( + obj@y, obj@x, obj@x2, + method_config$f_call, + method_config$f_cnst_y, + method_config$args_method, + paste0( + method_config$args_data, + ", ", + config$extra + ) + ) |> + as.list() + names(models) <- obj@x + obj@models <- models + } else { + cli::cli_abort("All focal variables were filtered out. Consider relaxing filtering criteria.") + } + } + ms <- br_get_models(obj) config <- br_get_config(obj) dots <- rlang::list2(...) diff --git a/R/98-utils.R b/R/98-utils.R index 7bfdf4a..3bb60ee 100644 --- a/R/98-utils.R +++ b/R/98-utils.R @@ -183,3 +183,100 @@ geom_segment_straight <- function(...) { utils::globalVariables( c("xend", "yend") ) + +# Variable filtering functions for br_run pre-filtering +filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e-6, filter_var_min = 1e-6) { + if (length(x) == 0) { + return(list( + filtered_x = character(0), + filtered_out = character(0), + filter_summary = list(total = 0, kept = 0, filtered = 0, prop_filtered = 0) + )) + } + + # Get variable names from terms (handle complex terms like I(x^2)) + x_vars <- sapply(x, get_vars) + x_simple <- x_vars[sapply(x_vars, function(v) length(v) == 1)] + + # For complex terms with multiple variables, we keep them for now + # Only filter simple single-variable terms + complex_terms <- x[sapply(x_vars, function(v) length(v) != 1)] + simple_terms <- x[sapply(x_vars, function(v) length(v) == 1)] + simple_vars <- x_simple + + if (length(simple_vars) == 0) { + return(list( + filtered_x = x, + filtered_out = character(0), + filter_summary = list(total = length(x), kept = length(x), filtered = 0, prop_filtered = 0) + )) + } + + # Check which variables are available in data + available_vars <- intersect(simple_vars, colnames(data)) + if (length(available_vars) == 0) { + return(list( + filtered_x = x, + filtered_out = character(0), + filter_summary = list(total = length(x), kept = length(x), filtered = 0, prop_filtered = 0) + )) + } + + # Filter based on criteria + filtered_out_vars <- character(0) + + for (var in available_vars) { + var_data <- data[[var]] + + # Skip if not numeric + if (!is.numeric(var_data)) { + next + } + + # Check NA proportion + na_prop <- sum(is.na(var_data)) / length(var_data) + if (na_prop > filter_na_prop) { + filtered_out_vars <- c(filtered_out_vars, var) + next + } + + # Get non-NA values for variance/sd checks + non_na_values <- var_data[!is.na(var_data)] + if (length(non_na_values) < 2) { + filtered_out_vars <- c(filtered_out_vars, var) + next + } + + # Check standard deviation + var_sd <- sd(non_na_values, na.rm = TRUE) + if (is.na(var_sd) || var_sd < filter_sd_min) { + filtered_out_vars <- c(filtered_out_vars, var) + next + } + + # Check variance + var_var <- var(non_na_values, na.rm = TRUE) + if (is.na(var_var) || var_var < filter_var_min) { + filtered_out_vars <- c(filtered_out_vars, var) + next + } + } + + # Map filtered variables back to terms + filtered_out_terms <- simple_terms[simple_vars %in% filtered_out_vars] + kept_terms <- setdiff(x, filtered_out_terms) + + # Create summary + filter_summary <- list( + total = length(x), + kept = length(kept_terms), + filtered = length(filtered_out_terms), + prop_filtered = length(filtered_out_terms) / length(x) + ) + + list( + filtered_x = kept_terms, + filtered_out = filtered_out_terms, + filter_summary = filter_summary + ) +} diff --git a/tests/testthat/Rplots.pdf b/tests/testthat/Rplots.pdf index 4a2f17e64159fffeb966737486f3d8ccda0e9017..dc8b614d032ead0121f8bfef8f6e107989361d86 100644 GIT binary patch delta 31 jcmcb$hvU{BjtSN*hDN4F6YV9ybYpaDG~?E2rvI`4vIGiu delta 31 jcmcb$hvU{BjtSN*2IfX)6YV9ybYpaDG~?E2rvI`4vZ4xs diff --git a/tests/testthat/test-filter-variables.R b/tests/testthat/test-filter-variables.R new file mode 100644 index 0000000..88463cc --- /dev/null +++ b/tests/testthat/test-filter-variables.R @@ -0,0 +1,118 @@ +test_that("Variable filtering works correctly", { + # Create test data with different types of problematic variables + set.seed(123) + n <- 100 + test_data <- data.frame( + y = rnorm(n), + good_var = rnorm(n, mean = 5, sd = 2), # Should pass all filters + high_na_var = c(rep(NA, 85), rnorm(15)), # 85% NA - should be filtered with default threshold + constant_var = rep(1, n), # Zero variance - should be filtered + near_constant_var = c(rep(1, 99), 1.0000001), # Very low variance - should be filtered + low_var = rnorm(n, mean = 0, sd = 1e-8), # Very low variance - should be filtered + categorical_var = sample(letters[1:3], n, replace = TRUE) # Categorical - should not be filtered + ) + + # Test filtering function directly + filter_result <- bregr:::filter_variables_x( + test_data, + c("good_var", "high_na_var", "constant_var", "near_constant_var", "low_var", "categorical_var"), + filter_na_prop = 0.8, + filter_sd_min = 1e-6, + filter_var_min = 1e-6 + ) + + # Should keep good_var and categorical_var (non-numeric) + expect_true("good_var" %in% filter_result$filtered_x) + expect_true("categorical_var" %in% filter_result$filtered_x) + + # Should filter out problematic variables + expect_true("high_na_var" %in% filter_result$filtered_out) + expect_true("constant_var" %in% filter_result$filtered_out) + expect_true("near_constant_var" %in% filter_result$filtered_out) + expect_true("low_var" %in% filter_result$filtered_out) + + # Check summary + expect_equal(filter_result$filter_summary$total, 6) + expect_equal(filter_result$filter_summary$filtered, 4) + expect_equal(filter_result$filter_summary$kept, 2) +}) + +test_that("br_run works with filtering disabled", { + # Test that existing functionality is not broken + m <- breg(mtcars) |> + br_set_y("mpg") |> + br_set_x("qsec") |> + br_set_model("gaussian") |> + br_run(filter_x = FALSE) + + expect_true(inherits(m, "bregr::breg")) + expect_true(nrow(m@results_tidy) > 0) +}) + +test_that("br_run works with filtering enabled", { + # Create test data where some variables should be filtered + set.seed(123) + test_data <- data.frame( + y = rnorm(50), + x1 = rnorm(50, sd = 2), # Good variable + x2 = c(rep(NA, 45), rnorm(5)), # Too many NAs + x3 = rep(1, 50) # Constant + ) + + # Expect message about filtering + expect_message( + m <- breg(test_data) |> + br_set_y("y") |> + br_set_x(c("x1", "x2", "x3")) |> + br_set_model("gaussian") |> + br_run(filter_x = TRUE), + "Pre-filtering removed" + ) + + expect_true(inherits(m, "bregr::breg")) + # Should only have results for x1 + expect_equal(length(unique(m@results_tidy$Focal_variable)), 1) + expect_true("x1" %in% m@results_tidy$Focal_variable) +}) + +test_that("br_pipeline works with filtering", { + # Create test data + set.seed(123) + test_data <- data.frame( + y = rnorm(50), + x1 = rnorm(50, sd = 2), # Good variable + x2 = rep(1, 50) # Constant - should be filtered + ) + + expect_message( + m <- br_pipeline( + test_data, + y = "y", + x = c("x1", "x2"), + method = "gaussian", + filter_x = TRUE + ), + "Pre-filtering removed" + ) + + expect_true(inherits(m, "bregr::breg")) + expect_equal(length(unique(m@results_tidy$Focal_variable)), 1) +}) + +test_that("Error when all variables are filtered out", { + # Create data where all focal variables should be filtered + test_data <- data.frame( + y = rnorm(50), + x1 = rep(1, 50), # Constant + x2 = rep(2, 50) # Constant + ) + + expect_error( + breg(test_data) |> + br_set_y("y") |> + br_set_x(c("x1", "x2")) |> + br_set_model("gaussian") |> + br_run(filter_x = TRUE), + "All focal variables were filtered out" + ) +}) \ No newline at end of file From 54537143a1ebe07d92c688ba520ebbd5ad9c94ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 9 Aug 2025 15:14:49 +0000 Subject: [PATCH 4/7] Add test artifacts to gitignore and final cleanup Co-authored-by: ShixiangWang <25057508+ShixiangWang@users.noreply.github.com> --- .gitignore | 3 +++ tests/testthat/Rplots.pdf | Bin 138842 -> 0 bytes 2 files changed, 3 insertions(+) delete mode 100644 tests/testthat/Rplots.pdf diff --git a/.gitignore b/.gitignore index f4f6c0b..614100c 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ bregr_models .Rapp.history *.png demo_fix.R + +# Test artifacts +tests/testthat/Rplots.pdf diff --git a/tests/testthat/Rplots.pdf b/tests/testthat/Rplots.pdf deleted file mode 100644 index dc8b614d032ead0121f8bfef8f6e107989361d86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138842 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 From 7ac60d05ce4a8d054d3561a60596842e1a45bd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Shixiang=20Wang=20=28=E7=8E=8B=E8=AF=97=E7=BF=94=29?= Date: Sat, 9 Aug 2025 23:23:12 +0800 Subject: [PATCH 5/7] update doc --- man/pipeline.Rd | 20 +++++++++++++++++-- .../test-roxytest-testexamples-02-pipeline.R | 2 +- .../test-roxytest-testexamples-04-show.R | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/man/pipeline.Rd b/man/pipeline.Rd index e06fa0b..b478414 100644 --- a/man/pipeline.Rd +++ b/man/pipeline.Rd @@ -20,7 +20,11 @@ br_pipeline( n_workers = 1L, run_parallel = lifecycle::deprecated(), model_args = list(), - run_args = list() + run_args = list(), + filter_x = FALSE, + filter_na_prop = 0.8, + filter_sd_min = 1e-06, + filter_var_min = 1e-06 ) br_set_y(obj, y) @@ -36,7 +40,11 @@ br_run( ..., group_by = NULL, n_workers = 1L, - run_parallel = lifecycle::deprecated() + run_parallel = lifecycle::deprecated(), + filter_x = FALSE, + filter_na_prop = 0.8, + filter_sd_min = 1e-06, + filter_var_min = 1e-06 ) } \arguments{ @@ -68,6 +76,14 @@ run modeling code in parallel in the background.} \item{run_args}{A list of arguments passed to \code{br_run()}.} +\item{filter_x}{Logical, whether to enable pre-filtering of focal variables. Default is \code{FALSE}.} + +\item{filter_na_prop}{Numeric, maximum proportion of NA values allowed for a variable. Default is \code{0.8}.} + +\item{filter_sd_min}{Numeric, minimum standard deviation required for a variable. Default is \code{1e-6}.} + +\item{filter_var_min}{Numeric, minimum variance required for a variable. Default is \code{1e-6}.} + \item{obj}{An object of class \code{breg}.} \item{...}{Additional arguments depending on the called function. diff --git a/tests/testthat/test-roxytest-testexamples-02-pipeline.R b/tests/testthat/test-roxytest-testexamples-02-pipeline.R index 9d37e84..069aebc 100644 --- a/tests/testthat/test-roxytest-testexamples-02-pipeline.R +++ b/tests/testthat/test-roxytest-testexamples-02-pipeline.R @@ -2,7 +2,7 @@ # File R/"02-pipeline.R": @testexamples -test_that("[unknown alias] @ L116", { +test_that("[unknown alias] @ L120", { library(bregr) # 1. Pipeline ------------------------- diff --git a/tests/testthat/test-roxytest-testexamples-04-show.R b/tests/testthat/test-roxytest-testexamples-04-show.R index 04728c6..cfaef7a 100644 --- a/tests/testthat/test-roxytest-testexamples-04-show.R +++ b/tests/testthat/test-roxytest-testexamples-04-show.R @@ -120,7 +120,7 @@ test_that("Function br_show_table_gt() @ L500", { }) -test_that("Function br_show_residuals() @ L737", { +test_that("Function br_show_residuals() @ L741", { m <- br_pipeline(mtcars, y = "mpg", From 889f53250ec7bf071ec225d23597e7892783537d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 9 Aug 2025 15:34:46 +0000 Subject: [PATCH 6/7] Enhance variable filtering to support categorical variables Co-authored-by: ShixiangWang <25057508+ShixiangWang@users.noreply.github.com> --- R/02-pipeline.R | 12 ++- R/98-utils.R | 48 ++++++---- tests/testthat/test-filter-variables.R | 121 ++++++++++++++++++++++++- 3 files changed, 157 insertions(+), 24 deletions(-) diff --git a/R/02-pipeline.R b/R/02-pipeline.R index 65d5cb3..34a3626 100644 --- a/R/02-pipeline.R +++ b/R/02-pipeline.R @@ -131,7 +131,8 @@ br_pipeline <- function( filter_x = FALSE, filter_na_prop = 0.8, filter_sd_min = 1e-6, - filter_var_min = 1e-6) { + filter_var_min = 1e-6, + filter_min_levels = 2) { if (lifecycle::is_present(run_parallel)) { lifecycle::deprecate_warn("1.1.0", "bregr::br_run(run_parallel = )", "bregr::br_run(n_workers = )") n_workers <- run_parallel @@ -145,6 +146,7 @@ br_pipeline <- function( br_run(group_by = group_by, n_workers = n_workers, filter_x = filter_x, filter_na_prop = filter_na_prop, filter_sd_min = filter_sd_min, filter_var_min = filter_var_min, + filter_min_levels = filter_min_levels, !!!run_args) } @@ -287,6 +289,7 @@ br_set_model <- function(obj, method, ...) { #' @param filter_na_prop Numeric, maximum proportion of NA values allowed for a variable. Default is `0.8`. #' @param filter_sd_min Numeric, minimum standard deviation required for a variable. Default is `1e-6`. #' @param filter_var_min Numeric, minimum variance required for a variable. Default is `1e-6`. +#' @param filter_min_levels Numeric, minimum number of unique levels required for categorical variables. Default is `2`. #' @export br_run <- function(obj, ..., group_by = NULL, n_workers = 1L, @@ -294,7 +297,8 @@ br_run <- function(obj, ..., filter_x = FALSE, filter_na_prop = 0.8, filter_sd_min = 1e-6, - filter_var_min = 1e-6) { + filter_var_min = 1e-6, + filter_min_levels = 2) { assert_breg_obj(obj) assert_character(group_by, allow_na = FALSE, allow_null = TRUE) on.exit(invisible(gc())) @@ -332,12 +336,14 @@ br_run <- function(obj, ..., assert_number_decimal(filter_na_prop, min = 0, max = 1) assert_number_decimal(filter_sd_min, min = 0) assert_number_decimal(filter_var_min, min = 0) + assert_number_whole(filter_min_levels, min = 1) filter_result <- filter_variables_x( obj@data, obj@x, filter_na_prop = filter_na_prop, filter_sd_min = filter_sd_min, - filter_var_min = filter_var_min + filter_var_min = filter_var_min, + filter_min_levels = filter_min_levels ) obj@x <- filter_result$filtered_x diff --git a/R/98-utils.R b/R/98-utils.R index 3bb60ee..9ca485f 100644 --- a/R/98-utils.R +++ b/R/98-utils.R @@ -185,7 +185,7 @@ utils::globalVariables( ) # Variable filtering functions for br_run pre-filtering -filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e-6, filter_var_min = 1e-6) { +filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e-6, filter_var_min = 1e-6, filter_min_levels = 2) { if (length(x) == 0) { return(list( filtered_x = character(0), @@ -228,38 +228,46 @@ filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e for (var in available_vars) { var_data <- data[[var]] - # Skip if not numeric - if (!is.numeric(var_data)) { - next - } - - # Check NA proportion + # Check NA proportion (applies to all variable types) na_prop <- sum(is.na(var_data)) / length(var_data) if (na_prop > filter_na_prop) { filtered_out_vars <- c(filtered_out_vars, var) next } - # Get non-NA values for variance/sd checks + # Get non-NA values for further checks non_na_values <- var_data[!is.na(var_data)] if (length(non_na_values) < 2) { filtered_out_vars <- c(filtered_out_vars, var) next } - # Check standard deviation - var_sd <- sd(non_na_values, na.rm = TRUE) - if (is.na(var_sd) || var_sd < filter_sd_min) { - filtered_out_vars <- c(filtered_out_vars, var) - next - } - - # Check variance - var_var <- var(non_na_values, na.rm = TRUE) - if (is.na(var_var) || var_var < filter_var_min) { - filtered_out_vars <- c(filtered_out_vars, var) - next + # Handle numeric variables + if (is.numeric(var_data)) { + # Check standard deviation + var_sd <- sd(non_na_values, na.rm = TRUE) + if (is.na(var_sd) || var_sd < filter_sd_min) { + filtered_out_vars <- c(filtered_out_vars, var) + next + } + + # Check variance + var_var <- var(non_na_values, na.rm = TRUE) + if (is.na(var_var) || var_var < filter_var_min) { + filtered_out_vars <- c(filtered_out_vars, var) + next + } + } + # Handle categorical variables (character, factor, logical) + else if (is.character(var_data) || is.factor(var_data) || is.logical(var_data)) { + # Check number of unique levels + n_unique_levels <- length(unique(non_na_values)) + if (n_unique_levels < filter_min_levels) { + filtered_out_vars <- c(filtered_out_vars, var) + next + } } + # For other variable types, keep them (e.g., Date, POSIXt, etc.) } # Map filtered variables back to terms diff --git a/tests/testthat/test-filter-variables.R b/tests/testthat/test-filter-variables.R index 88463cc..e3b4b41 100644 --- a/tests/testthat/test-filter-variables.R +++ b/tests/testthat/test-filter-variables.R @@ -18,7 +18,8 @@ test_that("Variable filtering works correctly", { c("good_var", "high_na_var", "constant_var", "near_constant_var", "low_var", "categorical_var"), filter_na_prop = 0.8, filter_sd_min = 1e-6, - filter_var_min = 1e-6 + filter_var_min = 1e-6, + filter_min_levels = 2 ) # Should keep good_var and categorical_var (non-numeric) @@ -37,6 +38,61 @@ test_that("Variable filtering works correctly", { expect_equal(filter_result$filter_summary$kept, 2) }) +test_that("Categorical variable filtering works correctly", { + # Create test data with different types of categorical variables + set.seed(123) + n <- 100 + test_data <- data.frame( + y = rnorm(n), + # Character variables + good_char = sample(c("A", "B", "C"), n, replace = TRUE), # 3 levels - should pass + constant_char = rep("A", n), # 1 level - should be filtered + high_na_char = c(rep(NA, 85), sample(c("A", "B"), 15, replace = TRUE)), # High NA - should be filtered + + # Factor variables + good_factor = factor(sample(c("X", "Y", "Z"), n, replace = TRUE)), # 3 levels - should pass + constant_factor = factor(rep("X", n)), # 1 level - should be filtered + high_na_factor = factor(c(rep(NA, 85), sample(c("X", "Y"), 15, replace = TRUE))), # High NA - should be filtered + + # Logical variables + good_logical = sample(c(TRUE, FALSE), n, replace = TRUE), # 2 levels - should pass + constant_logical = rep(TRUE, n), # 1 level - should be filtered + + # Mixed with numeric + good_numeric = rnorm(n, sd = 2) # Should pass + ) + + all_vars <- c("good_char", "constant_char", "high_na_char", + "good_factor", "constant_factor", "high_na_factor", + "good_logical", "constant_logical", "good_numeric") + + # Test with default parameters + filter_result <- bregr:::filter_variables_x( + test_data, all_vars, + filter_na_prop = 0.8, + filter_sd_min = 1e-6, + filter_var_min = 1e-6, + filter_min_levels = 2 + ) + + # Should keep variables with sufficient levels/variance + expect_true("good_char" %in% filter_result$filtered_x) + expect_true("good_factor" %in% filter_result$filtered_x) + expect_true("good_logical" %in% filter_result$filtered_x) + expect_true("good_numeric" %in% filter_result$filtered_x) + + # Should filter out problematic variables + expect_true("constant_char" %in% filter_result$filtered_out) + expect_true("high_na_char" %in% filter_result$filtered_out) + expect_true("constant_factor" %in% filter_result$filtered_out) + expect_true("high_na_factor" %in% filter_result$filtered_out) + expect_true("constant_logical" %in% filter_result$filtered_out) + + # Check counts + expect_equal(filter_result$filter_summary$kept, 4) # 4 good variables + expect_equal(filter_result$filter_summary$filtered, 5) # 5 filtered variables +}) + test_that("br_run works with filtering disabled", { # Test that existing functionality is not broken m <- breg(mtcars) |> @@ -115,4 +171,67 @@ test_that("Error when all variables are filtered out", { br_run(filter_x = TRUE), "All focal variables were filtered out" ) +}) + +test_that("Categorical filtering with custom min_levels parameter", { + # Test custom min_levels parameter + test_data <- data.frame( + y = rnorm(50), + x1 = sample(c("A", "B"), 50, replace = TRUE), # 2 levels + x2 = sample(c("X", "Y", "Z"), 50, replace = TRUE) # 3 levels + ) + + # With min_levels = 3, x1 should be filtered out but x2 should pass + filter_result <- bregr:::filter_variables_x( + test_data, c("x1", "x2"), + filter_min_levels = 3 + ) + + expect_true("x2" %in% filter_result$filtered_x) + expect_true("x1" %in% filter_result$filtered_out) + expect_equal(filter_result$filter_summary$filtered, 1) + expect_equal(filter_result$filter_summary$kept, 1) +}) + +test_that("Integration with br_run and br_pipeline for categorical variables", { + # Create test data with categorical variables that should be filtered + set.seed(123) + test_data <- data.frame( + y = rnorm(50), + x1 = rnorm(50, sd = 2), # Good numeric variable + x2 = rep("constant", 50), # Constant categorical - should be filtered + x3 = sample(c("A", "B", "C"), 50, replace = TRUE) # Good categorical variable + ) + + # Test br_run + expect_message( + m1 <- breg(test_data) |> + br_set_y("y") |> + br_set_x(c("x1", "x2", "x3")) |> + br_set_model("gaussian") |> + br_run(filter_x = TRUE), + "Pre-filtering removed" + ) + + expect_true(inherits(m1, "bregr::breg")) + # Should only have results for x1 and x3 (x2 filtered out) + expect_equal(length(unique(m1@results_tidy$Focal_variable)), 2) + expect_true("x1" %in% m1@results_tidy$Focal_variable) + expect_true("x3" %in% m1@results_tidy$Focal_variable) + expect_false("x2" %in% m1@results_tidy$Focal_variable) + + # Test br_pipeline + expect_message( + m2 <- br_pipeline( + test_data, + y = "y", + x = c("x1", "x2", "x3"), + method = "gaussian", + filter_x = TRUE + ), + "Pre-filtering removed" + ) + + expect_true(inherits(m2, "bregr::breg")) + expect_equal(length(unique(m2@results_tidy$Focal_variable)), 2) }) \ No newline at end of file From bd57aa1e6554ec1a79011dd0a1c7e75fb55f5d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Shixiang=20Wang=20=28=E7=8E=8B=E8=AF=97=E7=BF=94=29?= Date: Sun, 10 Aug 2025 00:24:02 +0800 Subject: [PATCH 7/7] Improve variable filtering and update documentation Enhanced the variable filtering logic in filter_variables_x to better handle categorical variables and minimum level requirements. Updated br_run to enforce that br_set_x and br_set_y are called before execution. Improved documentation and examples for pipeline functions, and expanded unit tests to cover categorical filtering and edge cases. Minor code formatting and consistency improvements throughout. --- NAMESPACE | 1 + R/00-bregr-package.R | 2 +- R/02-pipeline.R | 37 +++-- R/04-show.R | 2 +- R/98-utils.R | 28 ++-- man/pipeline.Rd | 11 +- tests/testthat/test-filter-variables.R | 126 +++++++++--------- .../test-roxytest-testexamples-02-pipeline.R | 10 +- tests/testthat/test-survival-legend-order.R | 34 ++--- 9 files changed, 130 insertions(+), 121 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 72528df..cea357c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -72,6 +72,7 @@ importFrom(stats,cor) importFrom(stats,pchisq) importFrom(stats,predict) importFrom(stats,quantile) +importFrom(stats,sd) importFrom(survival,Surv) importFrom(survival,coxph) importFrom(survival,survdiff) diff --git a/R/00-bregr-package.R b/R/00-bregr-package.R index 898e3aa..4239d06 100644 --- a/R/00-bregr-package.R +++ b/R/00-bregr-package.R @@ -9,7 +9,7 @@ #' @importFrom lifecycle deprecated #' @importFrom rlang .data .env #' @importFrom utils combn packageDescription packageVersion -#' @importFrom stats cor pchisq quantile predict +#' @importFrom stats cor pchisq quantile predict sd #' @rawNamespace if (getRversion() < "4.3.0") importFrom("S7", "@") ## usethis namespace: end NULL diff --git a/R/02-pipeline.R b/R/02-pipeline.R index 34a3626..53e3c28 100644 --- a/R/02-pipeline.R +++ b/R/02-pipeline.R @@ -101,9 +101,10 @@ #' ) #' #' # 3. Customized model ----------- +#' \dontrun{ #' dt <- data.frame(x = rnorm(100)) #' dt$y <- rpois(100, exp(1 + dt$x)) -#' \donttest{ +#' #' m5 <- breg(dt) |> #' br_set_y("y") |> #' br_set_x("x") |> @@ -143,11 +144,13 @@ br_pipeline <- function( br_set_x(x) |> br_set_x2(x2) |> br_set_model(method = method, !!!model_args) |> - br_run(group_by = group_by, n_workers = n_workers, - filter_x = filter_x, filter_na_prop = filter_na_prop, - filter_sd_min = filter_sd_min, filter_var_min = filter_var_min, - filter_min_levels = filter_min_levels, - !!!run_args) + br_run( + group_by = group_by, n_workers = n_workers, + filter_x = filter_x, filter_na_prop = filter_na_prop, + filter_sd_min = filter_sd_min, filter_var_min = filter_var_min, + filter_min_levels = filter_min_levels, + !!!run_args + ) } #' @describeIn pipeline Set dependent variables for model construction. @@ -301,6 +304,12 @@ br_run <- function(obj, ..., filter_min_levels = 2) { assert_breg_obj(obj) assert_character(group_by, allow_na = FALSE, allow_null = TRUE) + if (br_get_n_x(obj) < 1) { + cli::cli_abort("{.fn br_set_x} must run before {.fn br_run}") + } + if (length(br_get_y(obj)) < 1) { + cli::cli_abort("{.fn br_set_y} must run before {.fn br_run}") + } on.exit(invisible(gc())) if (lifecycle::is_present(run_parallel)) { @@ -331,23 +340,23 @@ br_run <- function(obj, ..., # Apply variable filtering if enabled original_x <- obj@x - if (filter_x && length(obj@x) > 0) { + if (filter_x) { assert_logical(filter_x, allow_na = FALSE) assert_number_decimal(filter_na_prop, min = 0, max = 1) assert_number_decimal(filter_sd_min, min = 0) assert_number_decimal(filter_var_min, min = 0) assert_number_whole(filter_min_levels, min = 1) - + filter_result <- filter_variables_x( - obj@data, obj@x, + obj@data, obj@x, filter_na_prop = filter_na_prop, filter_sd_min = filter_sd_min, filter_var_min = filter_var_min, filter_min_levels = filter_min_levels ) - + obj@x <- filter_result$filtered_x - + # Inform user about filtering results if (filter_result$filter_summary$filtered > 0) { cli::cli_inform( @@ -361,18 +370,18 @@ br_run <- function(obj, ..., } else { cli::cli_inform("Pre-filtering: no variables were filtered out") } - + # Update models to reflect filtered variables if (length(obj@x) > 0) { config <- br_get_config(obj) - + # Get the proper method configuration if (!rlang::is_list(config$method)) { method_config <- br_avail_method_config(config$method) } else { method_config <- config$method } - + models <- gen_template( obj@y, obj@x, obj@x2, method_config$f_call, diff --git a/R/04-show.R b/R/04-show.R index c1572e6..2c533f4 100644 --- a/R/04-show.R +++ b/R/04-show.R @@ -656,7 +656,7 @@ br_show_survival_curves <- function(breg, # Clean group names while preserving factor level order plot_data$group <- gsub(".*=", "", plot_data$group) - + # Convert back to factor with the same level order as the original group_labels # to ensure correct legend ordering plot_data$group <- factor(plot_data$group, levels = group_labels) diff --git a/R/98-utils.R b/R/98-utils.R index 9ca485f..c4df912 100644 --- a/R/98-utils.R +++ b/R/98-utils.R @@ -193,17 +193,17 @@ filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e filter_summary = list(total = 0, kept = 0, filtered = 0, prop_filtered = 0) )) } - + # Get variable names from terms (handle complex terms like I(x^2)) x_vars <- sapply(x, get_vars) x_simple <- x_vars[sapply(x_vars, function(v) length(v) == 1)] - + # For complex terms with multiple variables, we keep them for now # Only filter simple single-variable terms complex_terms <- x[sapply(x_vars, function(v) length(v) != 1)] simple_terms <- x[sapply(x_vars, function(v) length(v) == 1)] simple_vars <- x_simple - + if (length(simple_vars) == 0) { return(list( filtered_x = x, @@ -211,7 +211,7 @@ filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e filter_summary = list(total = length(x), kept = length(x), filtered = 0, prop_filtered = 0) )) } - + # Check which variables are available in data available_vars <- intersect(simple_vars, colnames(data)) if (length(available_vars) == 0) { @@ -221,27 +221,27 @@ filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e filter_summary = list(total = length(x), kept = length(x), filtered = 0, prop_filtered = 0) )) } - + # Filter based on criteria filtered_out_vars <- character(0) - + for (var in available_vars) { var_data <- data[[var]] - + # Check NA proportion (applies to all variable types) na_prop <- sum(is.na(var_data)) / length(var_data) if (na_prop > filter_na_prop) { filtered_out_vars <- c(filtered_out_vars, var) next } - + # Get non-NA values for further checks non_na_values <- var_data[!is.na(var_data)] if (length(non_na_values) < 2) { filtered_out_vars <- c(filtered_out_vars, var) next } - + # Handle numeric variables if (is.numeric(var_data)) { # Check standard deviation @@ -250,14 +250,14 @@ filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e filtered_out_vars <- c(filtered_out_vars, var) next } - + # Check variance var_var <- var(non_na_values, na.rm = TRUE) if (is.na(var_var) || var_var < filter_var_min) { filtered_out_vars <- c(filtered_out_vars, var) next } - } + } # Handle categorical variables (character, factor, logical) else if (is.character(var_data) || is.factor(var_data) || is.logical(var_data)) { # Check number of unique levels @@ -269,11 +269,11 @@ filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e } # For other variable types, keep them (e.g., Date, POSIXt, etc.) } - + # Map filtered variables back to terms filtered_out_terms <- simple_terms[simple_vars %in% filtered_out_vars] kept_terms <- setdiff(x, filtered_out_terms) - + # Create summary filter_summary <- list( total = length(x), @@ -281,7 +281,7 @@ filter_variables_x <- function(data, x, filter_na_prop = 0.8, filter_sd_min = 1e filtered = length(filtered_out_terms), prop_filtered = length(filtered_out_terms) / length(x) ) - + list( filtered_x = kept_terms, filtered_out = filtered_out_terms, diff --git a/man/pipeline.Rd b/man/pipeline.Rd index b478414..0d6a510 100644 --- a/man/pipeline.Rd +++ b/man/pipeline.Rd @@ -24,7 +24,8 @@ br_pipeline( filter_x = FALSE, filter_na_prop = 0.8, filter_sd_min = 1e-06, - filter_var_min = 1e-06 + filter_var_min = 1e-06, + filter_min_levels = 2 ) br_set_y(obj, y) @@ -44,7 +45,8 @@ br_run( filter_x = FALSE, filter_na_prop = 0.8, filter_sd_min = 1e-06, - filter_var_min = 1e-06 + filter_var_min = 1e-06, + filter_min_levels = 2 ) } \arguments{ @@ -84,6 +86,8 @@ run modeling code in parallel in the background.} \item{filter_var_min}{Numeric, minimum variance required for a variable. Default is \code{1e-6}.} +\item{filter_min_levels}{Numeric, minimum number of unique levels required for categorical variables. Default is \code{2}.} + \item{obj}{An object of class \code{breg}.} \item{...}{Additional arguments depending on the called function. @@ -182,9 +186,10 @@ m4 <- br_pipeline(mtcars, ) # 3. Customized model ----------- +\dontrun{ dt <- data.frame(x = rnorm(100)) dt$y <- rpois(100, exp(1 + dt$x)) -\donttest{ + m5 <- breg(dt) |> br_set_y("y") |> br_set_x("x") |> diff --git a/tests/testthat/test-filter-variables.R b/tests/testthat/test-filter-variables.R index e3b4b41..9862685 100644 --- a/tests/testthat/test-filter-variables.R +++ b/tests/testthat/test-filter-variables.R @@ -4,34 +4,34 @@ test_that("Variable filtering works correctly", { n <- 100 test_data <- data.frame( y = rnorm(n), - good_var = rnorm(n, mean = 5, sd = 2), # Should pass all filters - high_na_var = c(rep(NA, 85), rnorm(15)), # 85% NA - should be filtered with default threshold - constant_var = rep(1, n), # Zero variance - should be filtered - near_constant_var = c(rep(1, 99), 1.0000001), # Very low variance - should be filtered - low_var = rnorm(n, mean = 0, sd = 1e-8), # Very low variance - should be filtered - categorical_var = sample(letters[1:3], n, replace = TRUE) # Categorical - should not be filtered - ) - + good_var = rnorm(n, mean = 5, sd = 2), # Should pass all filters + high_na_var = c(rep(NA, 85), rnorm(15)), # 85% NA - should be filtered with default threshold + constant_var = rep(1, n), # Zero variance - should be filtered + near_constant_var = c(rep(1, 99), 1.0000001), # Very low variance - should be filtered + low_var = rnorm(n, mean = 0, sd = 1e-8), # Very low variance - should be filtered + categorical_var = sample(letters[1:3], n, replace = TRUE) # Categorical - should not be filtered + ) + # Test filtering function directly filter_result <- bregr:::filter_variables_x( - test_data, + test_data, c("good_var", "high_na_var", "constant_var", "near_constant_var", "low_var", "categorical_var"), filter_na_prop = 0.8, filter_sd_min = 1e-6, filter_var_min = 1e-6, filter_min_levels = 2 ) - + # Should keep good_var and categorical_var (non-numeric) expect_true("good_var" %in% filter_result$filtered_x) expect_true("categorical_var" %in% filter_result$filtered_x) - + # Should filter out problematic variables expect_true("high_na_var" %in% filter_result$filtered_out) - expect_true("constant_var" %in% filter_result$filtered_out) + expect_true("constant_var" %in% filter_result$filtered_out) expect_true("near_constant_var" %in% filter_result$filtered_out) expect_true("low_var" %in% filter_result$filtered_out) - + # Check summary expect_equal(filter_result$filter_summary$total, 6) expect_equal(filter_result$filter_summary$filtered, 4) @@ -45,27 +45,29 @@ test_that("Categorical variable filtering works correctly", { test_data <- data.frame( y = rnorm(n), # Character variables - good_char = sample(c("A", "B", "C"), n, replace = TRUE), # 3 levels - should pass - constant_char = rep("A", n), # 1 level - should be filtered - high_na_char = c(rep(NA, 85), sample(c("A", "B"), 15, replace = TRUE)), # High NA - should be filtered - + good_char = sample(c("A", "B", "C"), n, replace = TRUE), # 3 levels - should pass + constant_char = rep("A", n), # 1 level - should be filtered + high_na_char = c(rep(NA, 85), sample(c("A", "B"), 15, replace = TRUE)), # High NA - should be filtered + # Factor variables - good_factor = factor(sample(c("X", "Y", "Z"), n, replace = TRUE)), # 3 levels - should pass - constant_factor = factor(rep("X", n)), # 1 level - should be filtered - high_na_factor = factor(c(rep(NA, 85), sample(c("X", "Y"), 15, replace = TRUE))), # High NA - should be filtered - + good_factor = factor(sample(c("X", "Y", "Z"), n, replace = TRUE)), # 3 levels - should pass + constant_factor = factor(rep("X", n)), # 1 level - should be filtered + high_na_factor = factor(c(rep(NA, 85), sample(c("X", "Y"), 15, replace = TRUE))), # High NA - should be filtered + # Logical variables - good_logical = sample(c(TRUE, FALSE), n, replace = TRUE), # 2 levels - should pass - constant_logical = rep(TRUE, n), # 1 level - should be filtered - + good_logical = sample(c(TRUE, FALSE), n, replace = TRUE), # 2 levels - should pass + constant_logical = rep(TRUE, n), # 1 level - should be filtered + # Mixed with numeric - good_numeric = rnorm(n, sd = 2) # Should pass + good_numeric = rnorm(n, sd = 2) # Should pass + ) + + all_vars <- c( + "good_char", "constant_char", "high_na_char", + "good_factor", "constant_factor", "high_na_factor", + "good_logical", "constant_logical", "good_numeric" ) - - all_vars <- c("good_char", "constant_char", "high_na_char", - "good_factor", "constant_factor", "high_na_factor", - "good_logical", "constant_logical", "good_numeric") - + # Test with default parameters filter_result <- bregr:::filter_variables_x( test_data, all_vars, @@ -74,23 +76,23 @@ test_that("Categorical variable filtering works correctly", { filter_var_min = 1e-6, filter_min_levels = 2 ) - + # Should keep variables with sufficient levels/variance expect_true("good_char" %in% filter_result$filtered_x) expect_true("good_factor" %in% filter_result$filtered_x) expect_true("good_logical" %in% filter_result$filtered_x) expect_true("good_numeric" %in% filter_result$filtered_x) - + # Should filter out problematic variables expect_true("constant_char" %in% filter_result$filtered_out) expect_true("high_na_char" %in% filter_result$filtered_out) expect_true("constant_factor" %in% filter_result$filtered_out) expect_true("high_na_factor" %in% filter_result$filtered_out) expect_true("constant_logical" %in% filter_result$filtered_out) - + # Check counts - expect_equal(filter_result$filter_summary$kept, 4) # 4 good variables - expect_equal(filter_result$filter_summary$filtered, 5) # 5 filtered variables + expect_equal(filter_result$filter_summary$kept, 4) # 4 good variables + expect_equal(filter_result$filter_summary$filtered, 5) # 5 filtered variables }) test_that("br_run works with filtering disabled", { @@ -100,7 +102,7 @@ test_that("br_run works with filtering disabled", { br_set_x("qsec") |> br_set_model("gaussian") |> br_run(filter_x = FALSE) - + expect_true(inherits(m, "bregr::breg")) expect_true(nrow(m@results_tidy) > 0) }) @@ -110,11 +112,11 @@ test_that("br_run works with filtering enabled", { set.seed(123) test_data <- data.frame( y = rnorm(50), - x1 = rnorm(50, sd = 2), # Good variable - x2 = c(rep(NA, 45), rnorm(5)), # Too many NAs - x3 = rep(1, 50) # Constant + x1 = rnorm(50, sd = 2), # Good variable + x2 = c(rep(NA, 45), rnorm(5)), # Too many NAs + x3 = rep(1, 50) # Constant ) - + # Expect message about filtering expect_message( m <- breg(test_data) |> @@ -124,7 +126,7 @@ test_that("br_run works with filtering enabled", { br_run(filter_x = TRUE), "Pre-filtering removed" ) - + expect_true(inherits(m, "bregr::breg")) # Should only have results for x1 expect_equal(length(unique(m@results_tidy$Focal_variable)), 1) @@ -136,10 +138,10 @@ test_that("br_pipeline works with filtering", { set.seed(123) test_data <- data.frame( y = rnorm(50), - x1 = rnorm(50, sd = 2), # Good variable - x2 = rep(1, 50) # Constant - should be filtered + x1 = rnorm(50, sd = 2), # Good variable + x2 = rep(1, 50) # Constant - should be filtered ) - + expect_message( m <- br_pipeline( test_data, @@ -150,7 +152,7 @@ test_that("br_pipeline works with filtering", { ), "Pre-filtering removed" ) - + expect_true(inherits(m, "bregr::breg")) expect_equal(length(unique(m@results_tidy$Focal_variable)), 1) }) @@ -159,10 +161,10 @@ test_that("Error when all variables are filtered out", { # Create data where all focal variables should be filtered test_data <- data.frame( y = rnorm(50), - x1 = rep(1, 50), # Constant - x2 = rep(2, 50) # Constant + x1 = rep(1, 50), # Constant + x2 = rep(2, 50) # Constant ) - + expect_error( breg(test_data) |> br_set_y("y") |> @@ -177,16 +179,16 @@ test_that("Categorical filtering with custom min_levels parameter", { # Test custom min_levels parameter test_data <- data.frame( y = rnorm(50), - x1 = sample(c("A", "B"), 50, replace = TRUE), # 2 levels - x2 = sample(c("X", "Y", "Z"), 50, replace = TRUE) # 3 levels + x1 = sample(c("A", "B"), 50, replace = TRUE), # 2 levels + x2 = sample(c("X", "Y", "Z"), 50, replace = TRUE) # 3 levels ) - + # With min_levels = 3, x1 should be filtered out but x2 should pass filter_result <- bregr:::filter_variables_x( test_data, c("x1", "x2"), filter_min_levels = 3 ) - + expect_true("x2" %in% filter_result$filtered_x) expect_true("x1" %in% filter_result$filtered_out) expect_equal(filter_result$filter_summary$filtered, 1) @@ -198,11 +200,11 @@ test_that("Integration with br_run and br_pipeline for categorical variables", { set.seed(123) test_data <- data.frame( y = rnorm(50), - x1 = rnorm(50, sd = 2), # Good numeric variable - x2 = rep("constant", 50), # Constant categorical - should be filtered - x3 = sample(c("A", "B", "C"), 50, replace = TRUE) # Good categorical variable + x1 = rnorm(50, sd = 2), # Good numeric variable + x2 = rep("constant", 50), # Constant categorical - should be filtered + x3 = sample(c("A", "B", "C"), 50, replace = TRUE) # Good categorical variable ) - + # Test br_run expect_message( m1 <- breg(test_data) |> @@ -212,26 +214,26 @@ test_that("Integration with br_run and br_pipeline for categorical variables", { br_run(filter_x = TRUE), "Pre-filtering removed" ) - + expect_true(inherits(m1, "bregr::breg")) # Should only have results for x1 and x3 (x2 filtered out) expect_equal(length(unique(m1@results_tidy$Focal_variable)), 2) expect_true("x1" %in% m1@results_tidy$Focal_variable) expect_true("x3" %in% m1@results_tidy$Focal_variable) expect_false("x2" %in% m1@results_tidy$Focal_variable) - - # Test br_pipeline + + # Test br_pipeline expect_message( m2 <- br_pipeline( test_data, - y = "y", + y = "y", x = c("x1", "x2", "x3"), method = "gaussian", filter_x = TRUE ), "Pre-filtering removed" ) - + expect_true(inherits(m2, "bregr::breg")) expect_equal(length(unique(m2@results_tidy$Focal_variable)), 2) -}) \ No newline at end of file +}) diff --git a/tests/testthat/test-roxytest-testexamples-02-pipeline.R b/tests/testthat/test-roxytest-testexamples-02-pipeline.R index 069aebc..9685bad 100644 --- a/tests/testthat/test-roxytest-testexamples-02-pipeline.R +++ b/tests/testthat/test-roxytest-testexamples-02-pipeline.R @@ -2,7 +2,7 @@ # File R/"02-pipeline.R": @testexamples -test_that("[unknown alias] @ L120", { +test_that("[unknown alias] @ L121", { library(bregr) # 1. Pipeline ------------------------- @@ -45,14 +45,6 @@ test_that("[unknown alias] @ L120", { ) # 3. Customized model ----------- - dt <- data.frame(x = rnorm(100)) - dt$y <- rpois(100, exp(1 + dt$x)) - - m5 <- breg(dt) |> - br_set_y("y") |> - br_set_x("x") |> - br_set_model(method = 'quasi(variance = "mu", link = "log")') |> - br_run() assert_breg_obj(m) diff --git a/tests/testthat/test-survival-legend-order.R b/tests/testthat/test-survival-legend-order.R index 5b53bc9..022cf2a 100644 --- a/tests/testthat/test-survival-legend-order.R +++ b/tests/testthat/test-survival-legend-order.R @@ -1,10 +1,10 @@ test_that("br_show_survival_curves legend shows groups in correct order", { skip_if_not_installed("survival") skip_if_not_installed("ggplot2") - + library(bregr) library(ggplot2) - + # Create test data with predictable risk scores set.seed(123) n <- 100 @@ -12,53 +12,53 @@ test_that("br_show_survival_curves legend shows groups in correct order", { time = rexp(n, 0.01), status = rbinom(n, 1, 0.7), risk_score = c( - rnorm(33, -1, 0.2), # Low scores for low risk - rnorm(33, 0, 0.2), # Medium scores for medium risk - rnorm(34, 1, 0.2) # High scores for high risk + rnorm(33, -1, 0.2), # Low scores for low risk + rnorm(33, 0, 0.2), # Medium scores for medium risk + rnorm(34, 1, 0.2) # High scores for high risk ), age = rnorm(n, 60, 10), sex = factor(sample(c("M", "F"), n, replace = TRUE)) ) - + # Create breg object with Cox regression breg_obj <- br_pipeline( test_data, y = c("time", "status"), - x = "risk_score", + x = "risk_score", x2 = "sex", method = "coxph" ) - + # Test 3 groups - should be "Low Risk", "Medium Risk", "High Risk" p3 <- br_show_survival_curves(breg_obj, n_groups = 3) expect_s3_class(p3, "ggplot") - + # The legend order should be determined by factor levels in the plot data # Check that the group factor has the correct levels in the right order plot_data <- ggplot_build(p3)$data[[1]] - + # For 3 groups, the factor levels should be Low Risk, Medium Risk, High Risk expected_levels <- c("Low Risk", "Medium Risk", "High Risk") - + # Since the plot data group column should be numeric references to factor levels, # let's check the underlying plot object instead plot_env <- ggplot2::ggplot_build(p3) - + # Better approach: check that when we build the plot, the groups appear in expected order # The group numbers should correspond to factor levels, so group 1 = Low Risk, etc. unique_groups_nums <- sort(unique(plot_data$group)) expect_equal(length(unique_groups_nums), 3) expect_equal(unique_groups_nums, c(1, 2, 3)) - - # Test 5 groups - should be "Q1", "Q2", "Q3", "Q4", "Q5" + + # Test 5 groups - should be "Q1", "Q2", "Q3", "Q4", "Q5" p5 <- br_show_survival_curves(breg_obj, n_groups = 5) expect_s3_class(p5, "ggplot") - + # Extract the plot data to check legend order plot_data5 <- ggplot_build(p5)$data[[1]] unique_groups5_nums <- sort(unique(plot_data5$group)) - + # Groups should be numbered 1-5 corresponding to Q1-Q5 expect_equal(length(unique_groups5_nums), 5) expect_equal(unique_groups5_nums, c(1, 2, 3, 4, 5)) -}) \ No newline at end of file +})