ggRandomForests: Visually Exploring Random Forests

August 26, 2026 · View on GitHub

cranlogs CRAN_Status_Badge R package version

active

R-CMD-check lint pkgdown Codecov test coverage

DOI

ggRandomForests overview: predicted survival, variable importance, OOB error, and partial dependence

ggRandomForests provides ggplot2-based diagnostic and exploration plots for random forests. It reads rfsrc fits from randomForestSRC::rfsrc(), varpro fits from varPro::varpro(), and rhf fits from randomForestRHF::rhf(), a random-hazard forest for time-to-event data whose predictor values can change during follow-up. It also supports randomForest fits. Supported minimum versions are randomForestSRC 3.4.0, varPro 3.1.0, and randomForestRHF 1.0.1. The package keeps the data step apart from the figure step, so you can inspect, save, or reuse the tidy object on its own.

Listed in the ggplot2 extensions gallery.

Installation

# CRAN (stable)
install.packages("ggRandomForests")

# Development version from GitHub
# install.packages("remotes")
remotes::install_github("ehrlinger/ggRandomForests")

Quick start

library(randomForestSRC)
library(ggRandomForests)

# 1. Fit a forest (regression)
rf <- rfsrc(medv ~ ., data = MASS::Boston, importance = TRUE)

# 2. Check convergence: did the forest grow enough trees?
plot(gg_error(rf))

# 3. Rank predictors by importance
plot(gg_vimp(rf))

# 4. Marginal dependence for top variables
gg_v <- gg_variable(rf)
plot(gg_v, xvar = "lstat")
plot(gg_v, xvar = rf$xvar.names, panel = TRUE, se = FALSE)

# 5. Partial dependence for a single predictor
pv <- plot.variable(rf, xvar.names = "lstat", partial = TRUE, show.plots = FALSE)
pd <- gg_partial(pv)
plot(pd)

For survival forests, see the package vignette:

vignette("ggRandomForests")

For Random Hazard Forests with predictors that change during follow-up, see the RHF vignette:

vignette("rhf", package = "ggRandomForests")

For variable importance with varPro — partial dependence, importance z-scores, beta importance, individual/local importance, and isolation forests — see the dedicated vignette:

vignette("varpro", package = "ggRandomForests")

The unsupervised varPro tools — gg_udependent(), gg_beta_uvarpro(), and gg_sdependent(), which read structure off a varPro::uvarpro() fit with no outcome — have their own short vignette:

vignette("uvarpro", package = "ggRandomForests")

Function reference

Grouped by what you are trying to look at. The first column is the function you call, the second is what you hand it.

The forest itself

FunctionInputWhat you get
gg_error()rfsrc / randomForestOOB error vs. number of trees
gg_vimp()rfsrc / randomForestVariable importance ranking
gg_rfsrc()rfsrc / randomForestPredicted vs. observed values
gg_variable()rfsrc / randomForestMarginal dependence data frame

Partial dependence

FunctionInputWhat you get
gg_partial()plot.variable outputPartial dependence (continuous + categorical)
gg_partial_rfsrc()rfsrc modelPartial dependence via partial.rfsrc
surv_partial.rfsrc()rfsrc survival forestSurvival partial dependence, one or more predictors
quantile_pts()numeric vectorQuantile cut points for coplot panels

Survival

FunctionInputWhat you get
gg_survival()rfsrc survival forest, or a data frameKaplan–Meier / Nelson–Aalen estimates
gg_brier()rfsrc (survival)Time-resolved Brier score and CRPS
kaplan()data frame + interval/censor columnsNonparametric Kaplan–Meier estimate
nelson()data frame + interval/censor columnsNonparametric Nelson–Aalen estimate

Classification and ROC

FunctionInputWhat you get
gg_roc()rfsrc / randomForest (class)ROC curve data
calc_roc()rfsrc / randomForest (class)The sensitivity/specificity sweep behind gg_roc()
calc_auc()gg_roc objectArea under the curve

Random Hazard Forests

For time-to-event data with predictors that change during follow-up, these read an rhf fit or a saved tree-size tuning object. A hazard is the event-risk rate at a particular time.

FunctionInputWhat you get
gg_rhf()rhf fitCase-specific hazard or cumulative-hazard curves
gg_auct()rhf fitTime-varying AUC curve for event-risk discrimination
gg_rhf_importance()rhf fitVariable-priority matrix across time windows
gg_tune_rhf()tune.treesize.rhf objectInspected tree-size tuning path

varPro — variable priority

These read a varpro fit rather than a forest. varPro::varpro() is the supervised fit; varPro::uvarpro() is the unsupervised one, which needs no outcome.

FunctionInputWhat you get
gg_varpro()varpro fitRelease-rule variable importance
gg_beta_varpro()varpro fitPer-variable lasso-beta importance
gg_ivarpro()varpro fitIndividual (local) variable importance
gg_partial_varpro()varpro fitPartial dependence (alias: gg_partialpro())
gg_isopro()isopro fitIsolation-forest anomaly scores
gg_udependent()uvarpro fitVariable dependency graph
gg_beta_uvarpro()uvarpro fitPer-variable lasso-beta importance
gg_sdependent()uvarpro fitSignal-variable detection
varpro_feature_names()character vectorOriginal names behind one-hot encoded features

SHAP

FunctionInputWhat you get
gg_shap()rfsrc / randomForestShapley additive explanation values
shap_importance()gg_shap objectGlobal importance bar chart
shap_beeswarm()gg_shap objectBeeswarm summary plot
shap_dependence()gg_shap objectDependence plot for one predictor

Each gg_* function has a matching plot() S3 method that hands back a single plottable object: a ggplot you extend with +, or a patchwork composite for the multi-panel methods. Every gg_* object also has print() and summary() methods: print() shows a short header at the REPL rather than dumping every row (use head() when you want the rows), and summary() gives you a diagnostics object you can print or keep.

Why ggRandomForests?

The package is built on one decision: keep the data step and the figure step apart. The gg_* functions pull a tidy data object out of the forest; the plot() methods turn that object into a ggplot2 figure. Two things follow from that split.

First, the data object stands on its own. It carries everything its plot needs, so you can save it, inspect it, or come back to it later without keeping the original forest — which can be large — in memory.

Second, you are never locked into the default figure. Because a plot() method returns a single plottable object (a ggplot, or a patchwork composite for the multi-panel methods), you can add layers, swap scales, or apply a theme; and if the default is not what you want, you can ignore it entirely and build the figure from the tidy data yourself.

Recent changes

See NEWS.md for the full changelog. Recent highlights:

  • v4.0.0 (development) Random Hazard Forests: gg_rhf() for case-specific event-risk curves, gg_auct() for time-varying discrimination, gg_rhf_importance() for variable priority across time windows, and gg_tune_rhf() for inspecting a saved tree-size tuning path.
  • v3.5.1 gg_roc() on an rfsrc forest now honors the documented which_outcome = 0, which had been returning an unusable two-row object; gg_partial_rfsrc() rejects a non-forest with a real error instead of "argument is of length zero". Also a test-only fix for the gcc-UBSAN report filed against 3.5.0.
  • v3.5.0 varPro fixes: plot.gg_varpro() no longer draws a phantom "NA" category, gg_partial_varpro() warns when you name a variable the fit cannot reach, and scale = "chf" now honors xvar.names instead of computing every variable. Vignette figures render with ragg, which cut the source tarball from 4.7 MB to 2.3 MB.
  • v3.4.0 Unsupervised varPro wrappers (gg_beta_uvarpro(), gg_sdependent()) with their own vignette; gg_partial_rfsrc() now handles factor predictors correctly.
  • v3.3.0 varPro partial plots default to interpretable scales — probability for classification, survival S(τ) for survival.
  • v3.1.0 varPro integration: release-rule importance, partial dependence, local importance, anomaly scores, and the dependency graph.

References

Breiman, L. (2001). Random forests, Machine Learning, 45:5–32.

Ishwaran H. and Kogalur U.B. (2026). Fast Unified Random Forests for Survival, Regression, and Classification (RF-SRC). R package version 3.6.2. https://cran.r-project.org/package=randomForestSRC

Ishwaran H. and Kogalur U.B. (2007). Random survival forests for R. R News 7(2), 25–31.

Ishwaran H., Kogalur U.B., Blackstone E.H. and Lauer M.S. (2008). Random survival forests. Ann. Appl. Statist. 2(3), 841–860.

Lu M. and Ishwaran H. (2024). Model-independent variable selection via the rule-based variable priority framework. arXiv preprint arXiv:2409.09003. https://arxiv.org/abs/2409.09003

Ishwaran H. and Kogalur U.B. (2026). Model-Independent Variable Selection via the Rule-Based Variable Priority. R package version 3.2.0. https://cran.r-project.org/package=varPro

Ishwaran H., Hsich E.M., Kogalur U.B. and Lee D.K.K. (2026). Random Hazard Forests. arXiv preprint arXiv:2608.21597. https://doi.org/10.48550/arXiv.2608.21597

Ishwaran H. and Kogalur U.B. (2026). randomForestRHF: Random Hazard Forests. R package version 1.0.1. https://cran.r-project.org/package=randomForestRHF

Liaw A. and Wiener M. (2002). Classification and Regression by randomForest. R News 2(3), 18–22.

Wickham H. (2009). ggplot2: Elegant Graphics for Data Analysis. Springer New York.