| Title: | Variable Selection via Cross-Validated Net Benefit |
|---|---|
| Description: | Performs exhaustive or groupwise (backward elimination) variable selection for binary outcome prediction models using cross-validated Net Benefit as the optimization criterion. It supports predictor costs, restricted cubic splines, interaction terms, permutation importance, and parallel computation. It includes visualizations for model comparison and variable importance. References include Vickers AJ & Elkin EB (2006) <doi:10.1177/0272989X06295361>, Van Calster B et al. (2018) <doi:10.1016/j.eururo.2018.08.038>, Vickers AJ et al. (2019) <doi:10.1186/s41512-019-0064-7>, and Baker SG et al. (2012) <doi:10.1515/1557-4679.1395>. |
| Authors: | Lasai Barreñada [aut, cre] (ORCID: <https://orcid.org/0000-0001-8020-0210>, Department of Development and Regeneration ; Leuven Unit for Health Technology Assessment Research (LUHTAR), KU Leuven, Belgium), Laure Wynants [aut] (ORCID: <https://orcid.org/0000-0002-3037-122X>, Department of Development and Regeneration, KU Leuven, Belgium; Leuven Unit for Health Technology Assessment Research (LUHTAR), KU Leuven, Belgium; Department of Epidemiology, CAPHRI Care and Public Health Research Institute, Maastricht University, Maastricht, Netherlands), Ewout W. Steyerberg [aut] (ORCID: <https://orcid.org/0000-0002-7787-0122>, Julius Centre for Health Sciences and Primary Care, University Medical Centre Utrecht, Utrecht, Netherlands), Andrew Vickers [aut] (ORCID: <https://orcid.org/0000-0003-1525-6503>, Department of Epidemiology and Biostatistics, Memorial Sloan Kettering Cancer Center, New York, NY, USA), Ben Van Calster [aut] (ORCID: <https://orcid.org/0000-0003-1613-7450>, Department of Development and Regeneration, KU Leuven, Belgium; Leuven Unit for Health Technology Assessment Research (LUHTAR), KU Leuven, Belgium; Julius Centre for Health Sciences and Primary Care, University Medical Centre Utrecht, Utrecht, Netherlands) |
| Maintainer: | Lasai Barreñada <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.1.1 |
| Built: | 2026-10-09 11:03:12 UTC |
| Source: | https://github.com/lasaibarrenada/nb_varsel |
Pre-computed results from an exhaustive Net Benefit-based variable selection applied to ovarian tumour data from the International Ovarian Tumour Analysis (IOTA) consortium (phases 1–3). The dataset contains model-level summary statistics for the top 20 models per predictor count, drawn from a full exhaustive search over all 65,535 (2^16 - 1) predictor combinations.
adnex_resultsadnex_results
A data frame with 293 rows and 23 columns:
Comma-separated list of predictor names included in the model.
Number of predictors in the model.
Cross-validated area under the ROC curve.
Cross-validated Brier score.
Sum of predictor group costs for the model.
Average cost-adjusted Net Benefit across thresholds and CV folds.
Average Net Benefit (without cost adjustment) across thresholds and CV folds.
Permutation importance (delta Net Benefit) for each
predictor. NA when the predictor is not included in the model.
The original patient-level data are not publicly available. This dataset
contains only aggregated model performance metrics and can be used to
demonstrate the all_subset_plot() and VIF_plot() visualisation functions.
The analysis used 16 candidate predictors for a binary outcome (malignant vs. benign ovarian tumour) with grouped predictor costs reflecting clinical history (free), ultrasound examination (moderate cost), and blood biomarker (higher cost). Five-fold cross-validation was used with restricted cubic splines (3 knots) for continuous predictors.
The 16 candidate predictors are:
Clinical history (no cost): patient age, family history of ovarian cancer, oncology centre, pain.
Ultrasound (moderate cost): maximum lesion diameter, proportion solid, number of locules > 10, papillary count, papillary presence, acoustic shadows, ascites, irregular walls, bilateral, colour score, maximum solid diameter.
Blood biomarker (higher cost): CA-125.
This is a filtered subset (top 20 models per number of predictors, ranked by
Avg_Adj_Net_Benefit) of the full 65,535-model exhaustive search. The
attribute "best_model_stats" contains the overall best model, and
"n_total_models" records the total number of evaluated models.
IOTA consortium data (phases 1–3). See https://iotaplus.org/en for information about the IOTA studies.
data(adnex_results) head(adnex_results) # Best model from the full search attr(adnex_results, "best_model_stats") # Visualise all_subset_plot(adnex_results, filter = 7, size_dot = 1) VIF_plot(adnex_results)$plotdata(adnex_results) head(adnex_results) # Best model from the full search attr(adnex_results, "best_model_stats") # Visualise all_subset_plot(adnex_results, filter = 7, size_dot = 1) VIF_plot(adnex_results)$plot
Creates a two-panel figure comparing model performance across all evaluated subsets. The upper panel shows the selected metric for each model, and the lower panel shows which predictors are included in each model.
all_subset_plot( all_models, metric = "Avg_Net_Benefit", y_axis = "Average Net Benefit", filter = 5, size_dot = 3, highlight_color = "red", tile_color = "#2A6EBB", p1_theme = NULL, p2_theme = NULL, data_dict = NULL )all_subset_plot( all_models, metric = "Avg_Net_Benefit", y_axis = "Average Net Benefit", filter = 5, size_dot = 3, highlight_color = "red", tile_color = "#2A6EBB", p1_theme = NULL, p2_theme = NULL, data_dict = NULL )
all_models |
Data frame returned in the |
metric |
Character string. Name of the column in |
y_axis |
Character string. Label for the y-axis in the top panel.
Defaults to |
filter |
Integer. Maximum number of models to display per number of predictors. Defaults to 5. |
size_dot |
Numeric. Point size used in the metric plot. Defaults to 3. |
highlight_color |
Character string. Color for the dashed reference
lines marking the best model. Defaults to |
tile_color |
Character string. Fill color used for included
predictors in the heatmap. Defaults to |
p1_theme |
A |
p2_theme |
A |
data_dict |
A named character vector used to relabel predictors.
Format: |
A patchwork object containing two stacked ggplot panels.
Performs exhaustive or groupwise variable selection for binary-outcome prediction models. Models are evaluated using cross-validated net benefit, with optional adjustment for predictor costs.
nb_varsel( data, outcome_var, costs = NULL, thresholds = seq(0.05, 0.3, by = 0.01), include_interactions = FALSE, mode = c("exhaustive", "groupwise"), group_size = 2, cv_folds = 5, seed = 123, verbose = TRUE, allow_parallel = TRUE, permutation = FALSE, splines = TRUE, n_knots = 3 )nb_varsel( data, outcome_var, costs = NULL, thresholds = seq(0.05, 0.3, by = 0.01), include_interactions = FALSE, mode = c("exhaustive", "groupwise"), group_size = 2, cv_folds = 5, seed = 123, verbose = TRUE, allow_parallel = TRUE, permutation = FALSE, splines = TRUE, n_knots = 3 )
data |
A data frame containing the predictor variables and the binary outcome. |
outcome_var |
Character string naming the binary outcome column (coded as 0/1 or as a two-level factor). |
costs |
Predictor costs. Can be:
|
thresholds |
Numeric vector of decision thresholds at which net
benefit is evaluated. Defaults to |
include_interactions |
Logical. If |
mode |
Character string specifying the selection strategy:
|
group_size |
Integer. Number of variables removed at each step in groupwise mode. Defaults to 2. |
cv_folds |
Integer. Number of cross-validation folds. Defaults to 5. |
seed |
Integer. Random seed for reproducibility. Defaults to 123. |
verbose |
Logical. If |
allow_parallel |
Logical. If |
permutation |
Logical. If |
splines |
Logical. If |
n_knots |
Integer. Number of knots used for restricted cubic splines. Defaults to 3. |
A list with the following elements:
A one-row data frame describing the top-performing model.
A data frame with one row per evaluated model,
containing columns Model, n_Preds, AUC, Brier,
Total_Cost, Avg_Adj_Net_Benefit, and Avg_Net_Benefit.
If permutation = TRUE, additional VIF_ columns containing
permutation importance scores are included.
set.seed(42) n <- 500 df <- data.frame( X1 = rnorm(n), X2 = rbinom(n, 1, 0.7), X3 = rnorm(n), X4 = rbinom(n, 1, 0.5) ) df$Y <- rbinom(n, 1, plogis(2 * df$X1 + 1.5 * df$X2)) harms <- c(X1 = 0.1, X2 = 0.05, X3 = 0.1, X4 = 0.0001) result <- nb_varsel( data = df, outcome_var = "Y", costs = harms, mode = "exhaustive", splines = FALSE, allow_parallel = FALSE ) result$best_model_statsset.seed(42) n <- 500 df <- data.frame( X1 = rnorm(n), X2 = rbinom(n, 1, 0.7), X3 = rnorm(n), X4 = rbinom(n, 1, 0.5) ) df$Y <- rbinom(n, 1, plogis(2 * df$X1 + 1.5 * df$X2)) harms <- c(X1 = 0.1, X2 = 0.05, X3 = 0.1, X4 = 0.0001) result <- nb_varsel( data = df, outcome_var = "Y", costs = harms, mode = "exhaustive", splines = FALSE, allow_parallel = FALSE ) result$best_model_stats
Creates a horizontal bar chart showing the average permutation importance of each predictor, measured as the change in net benefit relative to the full set of evaluated models.
VIF_plot(all_models, filter = NULL, color = "#2A6EBB", data_dict = NULL)VIF_plot(all_models, filter = NULL, color = "#2A6EBB", data_dict = NULL)
all_models |
Data frame returned in the |
filter |
Integer or |
color |
Character string. Fill color for the bars. Defaults to
|
data_dict |
A named character vector used to relabel predictors.
Format: |
A list with two elements:
A ggplot2::ggplot object showing the bar chart.
A data frame containing the Variable,
Average_Delta_NB, and mapped Label values.
data(adnex_results) vif_results <- VIF_plot(adnex_results) vif_results$plot head(vif_results$data)data(adnex_results) vif_results <- VIF_plot(adnex_results) vif_results$plot head(vif_results$data)