| Title: | Variable Selection via Cross-Validated Net Benefit |
| Version: | 0.1.1 |
| 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>. |
| License: | GPL (≥ 3) |
| URL: | https://lasaibarrenada.github.io/NB_varsel/, https://github.com/LasaiBarrenada/NB_varsel |
| BugReports: | https://github.com/LasaiBarrenada/NB_varsel/issues |
| Depends: | R (≥ 4.1.0) |
| Encoding: | UTF-8 |
| LazyData: | true |
| RoxygenNote: | 8.0.0 |
| Imports: | caret, DescTools, doParallel, dplyr, foreach, ggplot2, ggtext, parallel, patchwork, pROC, rlang, rms, scales, stats, stringr, tidyr |
| Suggests: | glmnet, ggsci, gt, knitr, quarto, testthat (≥ 3.0.0) |
| VignetteBuilder: | quarto |
| Config/testthat/edition: | 3 |
| NeedsCompilation: | no |
| Packaged: | 2026-08-21 12:17:31 UTC; u0158158 |
| Author: | Lasai Barreñada |
| Maintainer: | Lasai Barreñada <lasai.barrenadataleb@kuleuven.be> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-30 09:10:33 UTC |
NBvarsel: 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.
Author(s)
Maintainer: Lasai Barreñada lasai.barrenadataleb@kuleuven.be (ORCID) (Department of Development and Regeneration ; Leuven Unit for Health Technology Assessment Research (LUHTAR), KU Leuven, Belgium)
Authors:
Lasai Barreñada lasai.barrenadataleb@kuleuven.be (ORCID) (Department of Development and Regeneration ; Leuven Unit for Health Technology Assessment Research (LUHTAR), KU Leuven, Belgium)
Laure Wynants (ORCID) (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 (ORCID) (Julius Centre for Health Sciences and Primary Care, University Medical Centre Utrecht, Utrecht, Netherlands)
Andrew Vickers (ORCID) (Department of Epidemiology and Biostatistics, Memorial Sloan Kettering Cancer Center, New York, NY, USA)
Ben Van Calster (ORCID) (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)
See Also
Useful links:
Report bugs at https://github.com/LasaiBarrenada/NB_varsel/issues
Permutation Importance Bar Plot
Description
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.
Usage
VIF_plot(all_models, filter = NULL, color = "#2A6EBB", data_dict = NULL)
Arguments
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: |
Value
A list with two elements:
- plot
A ggplot2::ggplot object showing the bar chart.
- data
A data frame containing the
Variable,Average_Delta_NB, and mappedLabelvalues.
Examples
data(adnex_results)
vif_results <- VIF_plot(adnex_results)
vif_results$plot
head(vif_results$data)
ADNEX Exhaustive Variable Selection Results
Description
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.
Usage
adnex_results
Format
A data frame with 293 rows and 23 columns:
- Model
Comma-separated list of predictor names included in the model.
- n_Preds
Number of predictors in the model.
- AUC
Cross-validated area under the ROC curve.
- Brier
Cross-validated Brier score.
- Total_Cost
Sum of predictor group costs for the model.
- Avg_Adj_Net_Benefit
Average cost-adjusted Net Benefit across thresholds and CV folds.
- Avg_Net_Benefit
Average Net Benefit (without cost adjustment) across thresholds and CV folds.
- VIF_age, VIF_ca125, VIF_family_history, VIF_locules_gt_10, VIF_oncology_center, VIF_max_diam_lesion, VIF_papillary_count, VIF_acoustic_shadows, VIF_ascites, VIF_ireg_walls, VIF_bilateral, VIF_color_score, VIF_pain, VIF_max_diam_solid, VIF_papillary_presence, VIF_prop_solid
Permutation importance (delta Net Benefit) for each predictor.
NAwhen the predictor is not included in the model.
Details
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.
Source
IOTA consortium data (phases 1–3). See https://iotaplus.org/en for information about the IOTA studies.
Examples
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)$plot
All-Subset Model Comparison Plot
Description
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.
Usage
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
)
Arguments
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: |
Value
A patchwork object containing two stacked ggplot panels.
Variable Selection via Cross-Validated Net Benefit
Description
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.
Usage
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
)
Arguments
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. |
Value
A list with the following elements:
- best_model_stats
A one-row data frame describing the top-performing model.
- all_models
A data frame with one row per evaluated model, containing columns
Model,n_Preds,AUC,Brier,Total_Cost,Avg_Adj_Net_Benefit, andAvg_Net_Benefit. Ifpermutation = TRUE, additionalVIF_columns containing permutation importance scores are included.
Examples
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_stats