Busabase
Busabase is an open-source (MIT) database and workspace for AI agents — data, docs, skills, and apps in one place. Run it locally, self-host it inside your network, or use Busabase Cloud, and turn age
Graph-theoretic algorithms for removing redundant predictors based on pairwise correlation or association thresholds.
Translation pending
DataR · C++GitHub @gcol33OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
R package for exhaustive selection of variable subsets below a correlation threshold.
Translation pending
Loading the full README. The saved excerpt is shown below.
Exact enumeration of maximal predictor sets under a correlation threshold. Hand it a data frame and a threshold. corrselect finds every maximal set of predictors whose pairwise correlations all stay under that threshold, by graph enumeration (Bron–Kerbosch / Eppstein–Löffler–Strash) in C++, and returns whichever view you need: a single pruned data frame, or every valid subset to choose from. corrSelect() returns every maximal low-correlation subset, ranked by size then average correlation:Read the full README ↗
every uncorrelated subset of predictors
corrselect removes redundant predictors before modelling, either by keeping only predictors whose pairwise correlations do not exceed a threshold or by dropping predictors with a high variance inflation factor (VIF) from a regression model.
The correlation search treats each predictor as a node of a graph and joins two predictors when their correlation is at or below the threshold. Every set of predictors that can be kept together is then a clique of this graph. corrselect enumerates the maximal ones, the subsets to which no further predictor can be added, with the Bron–Kerbosch and Eppstein–Löffler–Strash algorithms in C++. It returns either one pruned data frame or every maximal subset, so you can choose the subset that keeps the variables your analysis needs.
corrselect supports:
corrPrune()
returns one data frame. It searches exactly up to 100 predictors
(max_exact_p) and switches to a greedy search in C++ beyond that.corrSelect()
returns every maximal subset, ranked by size and then by average
correlation.force_in keeps named
predictors in every result, and by requires the threshold to hold
within each group.modelPrune()
refits a model after each removal, by VIF or condition number, with
built-in engines for linear models, generalized linear models,
lme4 and
glmmTMB, and custom engines for
any other modelling package.In exact mode the result is the same on every run, and the largest subset it returns keeps at least as many predictors as any greedy removal at the same threshold. Theory and Formulation defines the threshold graph and the algorithms.
Install the released version from CRAN. Windows and macOS get a binary package and need no build tools:
install.packages("corrselect")
The development version compiles C++ code. Install the build tools for your operating system first:
| Operating system | Build tools |
|---|---|
| Windows | Rtools matching your R version |
| macOS | Run xcode-select --install in Terminal |
| Debian / Ubuntu | Install r-base-dev |
Check that R can find the compiler:
pkgbuild::has_build_tools(debug = TRUE)
Then install corrselect from GitHub:
# install.packages("pak")
pak::pak("gcol33/corrselect")
corrselect needs no system libraries beyond the compiler. Its C++ code links only to Rcpp, which is installed from CRAN with the package.
corrPrune().corrSelect() and take one out as a
data frame with corrSubset().modelPrune().The input is a data frame of candidate predictors, with numeric, factor or ordered columns. Correlations are computed on the rows without missing values, and the returned data frame keeps every row. The threshold defaults to 0.7.
library(corrselect)
pruned <- corrPrune(mtcars)
names(pruned)
#> [1] "mpg" "drat" "qsec" "gear" "carb"
Five of the eleven columns of mtcars remain, and no pair of them has a
correlation above 0.7. With eleven predictors the search is exact.
Several subsets usually satisfy the same threshold. corrSelect() lists
all maximal ones. corrSubset() returns one of them, the top-ranked by
default:
res <- corrSelect(mtcars)
res
#> CorrCombo object
#> -----------------
#> Method: bron-kerbosch
#> Correlation: pearson
#> Threshold: 0.700
#> Subsets: 15 maximal subsets
#> Data Rows: 32 used in correlation
#> Pivot: TRUE
#>
#> Top combinations:
#> No. Variables Avg Max Size
#> ------------------------------------------------------------
#> [ 1] mpg, drat, qsec, gear, carb 0.416 0.700 5
#> [ 2] cyl, drat, qsec, gear, carb 0.434 0.700 5
#> [ 3] mpg, drat, vs, gear, carb 0.466 0.700 5
#> [ 4] wt, qsec, am, carb 0.373 0.692 4
#> [ 5] wt, qsec, gear, carb 0.388 0.656 4
#> ... (10 more combinations)
best <- corrSubset(res, mtcars)
head(best, 3)
#> mpg drat qsec gear carb
#> Mazda RX4 21.0 3.90 16.46 4 4
#> Mazda RX4 Wag 21.0 3.90 17.02 4 4
#> Datsun 710 22.8 3.85 18.61 4 1
modelPrune() takes a model formula instead. It removes the predictor
with the highest VIF, refits, and repeats until no VIF exceeds 5:
fit <- modelPrune(mpg ~ cyl + disp + hp + wt, data = mtcars)
names(fit)
#> [1] "mpg" "cyl" "hp" "wt"
disp is removed, and the response stays in the returned data frame.
force_in keeps predictors in the result whatever else is removed. by
computes the correlations within each level of a grouping column, and
the threshold has to hold in every group:
corrPrune(mtcars, threshold = 0.7, force_in = c("hp", "wt"))
cols <- c("x1", "x2", "x3", "x4", "x5", "site")
long <- longitudinal_example[, cols]
corrPrune(long, threshold = 0.6, by = "site")
group_q relaxes the grouped rule to a quantile of the per-group
correlations. Advanced
Topics
shows it on simulated data.
assocSelect() enumerates maximal subsets of a data frame with numeric,
factor and ordered columns, with the measure chosen per pair:
set.seed(1)
df <- data.frame(
height = rnorm(30, 170, 10),
weight = rnorm(30, 70, 12),
group = factor(sample(c("A", "B"), 30, TRUE)),
rating = ordered(sample(c("low", "med", "high"), 30, TRUE))
)
assocSelect(df, threshold = 0.6)
corrPrune() uses the same measures, so one call handles all-numeric
and mixed data. For two numeric columns, measure selects one of six
measures, three of which need a suggested package; the corrPrune()
reference
lists them.
modelPrune() has built-in engines for linear models, generalized
linear models, lme4 and glmmTMB. With lme4 and glmmTMB only the fixed
effects are candidates for removal. Any other package plugs in as a
custom engine, a list of two functions: one that fits the model and one
that returns a score per fixed effect. Advanced
Topics
builds engines for INLA and
mgcv.
corrPrune() | modelPrune() | |
|---|---|---|
| Needs a model | No | Yes |
| Based on | Pairwise correlation or association | Model diagnostics (VIF, condition number) |
| Works without a response | Yes | No |
| Mixed models | No | Yes (lme4, glmmTMB) |
| Suited to | Exploratory analysis, many predictors | Regression workflows, VIF reduction |
Start with corrPrune() to reduce the number of predictors, then use
modelPrune() to remove the remaining collinearity within the model you
fit.
corrPrune() chooses the search mode from the number of predictors:
exact enumeration up to max_exact_p (100 by default) and the greedy
C++ search beyond that. Exact mode returns the largest subset that
satisfies the threshold. Greedy mode builds one subset by successive
removals and runs in time quadratic in the number of predictors, so it
handles wide data without that guarantee. mode sets either one:
corrPrune(mtcars, threshold = 0.7, mode = "exact")
corrPrune(mtcars, threshold = 0.7, mode = "greedy")
caret’s findCorrelation() removes
predictors one at a time: it takes the most correlated pair and drops
the member with the larger mean absolute correlation, until no pair
exceeds the cutoff. On mtcars at the same threshold, with caret 7.0.1:
drop <- caret::findCorrelation(cor(mtcars), cutoff = 0.7)
names(mtcars)[-drop]
#> [1] "qsec" "gear" "carb"
exact <- corrPrune(mtcars, threshold = 0.7, mode = "exact")
names(exact)
#> [1] "mpg" "drat" "qsec" "gear" "carb"
Comparison with Alternatives runs both on a larger dataset and sets corrselect beside Boruta, glmnet and manual VIF removal.
Start with Quick Start: each function on a small example, with its main arguments.
Questions and bug reports go to the GitHub issues. A bug report is easiest to act on with a small reproducible example, for instance made with reprex.
Pull requests are welcome; see the contributing guide.
“Software is like sex: it’s better when it’s free.” — Linus Torvalds
I’m a PhD student who builds R packages in my free time because I believe good tools should be free and open. I started these projects for my own work and figured others might find them useful too.
If this package saved you some time, buying me a coffee is a nice way to say thanks. It helps with my coffee addiction.
corrselect is licensed under MIT.
If you use corrselect, please cite the article in the Journal of Open Source Software and the package version you used.
Colling G (2026). "corrselect: Fast and flexible predictor pruning for
data analysis and modeling." _Journal of Open Source Software_,
*11*(118), 9539. doi:10.21105/joss.09539
<https://doi.org/10.21105/joss.09539>.
<https://joss.theoj.org/papers/10.21105/joss.09539>.
Colling G (2026). _corrselect: Correlation-Based and Model-Based
Predictor Pruning_. doi:10.32614/CRAN.package.corrselect
<https://doi.org/10.32614/CRAN.package.corrselect>. R package version
3.3.0, <https://gillescolling.com/corrselect/>.
BibTeX:
@Article{colling2026corrselectjoss,
title = {corrselect: Fast and flexible predictor pruning for data analysis and modeling},
author = {Gilles Colling},
journal = {Journal of Open Source Software},
year = {2026},
volume = {11},
number = {118},
pages = {9539},
doi = {10.21105/joss.09539},
url = {https://joss.theoj.org/papers/10.21105/joss.09539},
}
@Manual{colling2026corrselect,
title = {corrselect: Correlation-Based and Model-Based Predictor Pruning},
author = {Gilles Colling},
year = {2026},
note = {R package version 3.3.0},
doi = {10.32614/CRAN.package.corrselect},
url = {https://gillescolling.com/corrselect/},
}