R programming
ranger package
caret package
tuneGrid
machine learning

R using ranger with caret, tuneGrid argument

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

When using the ranger random forest implementation through the caret package in R, the tuneGrid argument specifies which hyperparameter combinations to test during model training. For ranger, the tunable parameters are mtry (number of variables per split), splitrule (splitting criterion), and min.node.size (minimum terminal node size). Incorrect parameter names or values in tuneGrid cause silent failures or errors.

Basic Usage

r
1library(caret)
2library(ranger)
3
4# Simple train call with default tuning
5model <- train(
6  Species ~ .,
7  data = iris,
8  method = "ranger",
9  trControl = trainControl(method = "cv", number = 5)
10)
11
12print(model)
13# Shows best mtry, splitrule, and min.node.size

Without tuneGrid, caret tests a default set of mtry values.

Specifying tuneGrid

r
1# Define the hyperparameter grid
2grid <- expand.grid(
3  mtry = c(2, 3, 4),                    # Variables per split
4  splitrule = c("gini", "extratrees"),   # Splitting criterion
5  min.node.size = c(1, 5, 10)           # Min terminal node size
6)
7
8print(grid)
9#   mtry  splitrule min.node.size
10# 1    2      gini             1
11# 2    3      gini             1
12# ...18 combinations total
13
14model <- train(
15  Species ~ .,
16  data = iris,
17  method = "ranger",
18  tuneGrid = grid,
19  trControl = trainControl(method = "cv", number = 5)
20)
21
22print(model$bestTune)
23# Shows the combination with highest accuracy

Parameter Details

mtry

Number of variables randomly sampled as candidates at each split:

r
1# For classification: default is sqrt(num_features)
2# For regression: default is num_features / 3
3
4# Must be between 1 and the total number of features
5grid <- expand.grid(
6  mtry = 1:ncol(iris) - 1,  # 1 to 4 for iris (exclude target)
7  splitrule = "gini",
8  min.node.size = 1
9)

splitrule

The criterion used to evaluate splits:

r
1# Classification:
2#   "gini"       — Gini impurity (default)
3#   "extratrees" — Extremely randomized trees (random split points)
4
5# Regression:
6#   "variance"   — Variance reduction (default)
7#   "extratrees" — Extremely randomized trees
8#   "maxstat"    — Maximally selected rank statistics
9
10grid <- expand.grid(
11  mtry = c(2, 3),
12  splitrule = c("variance", "extratrees"),  # Regression
13  min.node.size = c(5, 10)
14)

min.node.size

Minimum number of observations in a terminal node:

r
1# Classification default: 1
2# Regression default: 5
3# Larger values prevent overfitting
4
5grid <- expand.grid(
6  mtry = 3,
7  splitrule = "gini",
8  min.node.size = c(1, 5, 10, 20, 50)  # Test multiple sizes
9)

Complete Classification Example

r
1library(caret)
2library(ranger)
3
4set.seed(42)
5
6# Prepare data
7data(iris)
8train_idx <- createDataPartition(iris$Species, p = 0.8, list = FALSE)
9train_data <- iris[train_idx, ]
10test_data <- iris[-train_idx, ]
11
12# Define grid
13grid <- expand.grid(
14  mtry = c(2, 3, 4),
15  splitrule = c("gini", "extratrees"),
16  min.node.size = c(1, 5, 10)
17)
18
19# Train with cross-validation
20ctrl <- trainControl(
21  method = "repeatedcv",
22  number = 10,
23  repeats = 3,
24  classProbs = TRUE,
25  summaryFunction = multiClassSummary
26)
27
28model <- train(
29  Species ~ .,
30  data = train_data,
31  method = "ranger",
32  tuneGrid = grid,
33  trControl = ctrl,
34  importance = "impurity"  # Extra args passed to ranger
35)
36
37# Results
38print(model)
39plot(model)
40
41# Best parameters
42print(model$bestTune)
43
44# Predictions
45preds <- predict(model, test_data)
46confusionMatrix(preds, test_data$Species)

Complete Regression Example

r
1library(caret)
2
3set.seed(42)
4
5# Boston housing data
6data(mtcars)
7
8grid <- expand.grid(
9  mtry = c(2, 3, 5, 7),
10  splitrule = c("variance", "extratrees"),
11  min.node.size = c(3, 5, 10)
12)
13
14model <- train(
15  mpg ~ .,
16  data = mtcars,
17  method = "ranger",
18  tuneGrid = grid,
19  trControl = trainControl(method = "cv", number = 5),
20  num.trees = 500  # Passed to ranger
21)
22
23print(model)
24print(model$bestTune)

Using tuneLength Instead

If you do not want to specify exact values, tuneLength tells caret how many values to try:

r
1model <- train(
2  Species ~ .,
3  data = iris,
4  method = "ranger",
5  tuneLength = 5,  # caret picks 5 values for each parameter
6  trControl = trainControl(method = "cv", number = 5)
7)
8
9# caret auto-selects 5 mtry values, but may not vary splitrule or min.node.size

tuneLength is simpler but gives less control. tuneGrid is preferred for systematic exploration.

Passing Extra Arguments to ranger

Arguments not in tuneGrid are passed directly to ranger:

r
1model <- train(
2  Species ~ .,
3  data = iris,
4  method = "ranger",
5  tuneGrid = grid,
6  trControl = trainControl(method = "cv", number = 5),
7
8  # These go directly to ranger::ranger()
9  num.trees = 1000,
10  importance = "impurity",
11  respect.unordered.factors = TRUE,
12  seed = 42
13)
14
15# Variable importance
16varImp(model)

Visualizing Results

r
1# Plot accuracy vs hyperparameters
2plot(model)
3
4# Custom ggplot
5library(ggplot2)
6ggplot(model$results, aes(x = mtry, y = Accuracy, color = splitrule)) +
7  geom_line() +
8  geom_point() +
9  facet_wrap(~min.node.size) +
10  theme_minimal() +
11  labs(title = "Ranger Hyperparameter Tuning")

Common Pitfalls

  • Wrong parameter names: tuneGrid must use exactly mtry, splitrule, and min.node.size. Using nodesize or split_rule silently fails or throws an error.
  • Mismatched splitrule for task type: Using "gini" for regression or "variance" for classification causes an error. Match the splitrule to your problem type.
  • mtry too large: mtry cannot exceed the number of predictor variables. expand.grid(mtry = 1:20, ...) on a 5-feature dataset causes an error at mtry > 5.
  • Not setting a seed: Random forest results vary between runs. Always use set.seed() before train() for reproducible results.
  • Ignoring num.trees: The default is 500 trees. For small mtry values, more trees may be needed for stable results. Pass num.trees = 1000 or higher as an extra argument.

Summary

  • tuneGrid for ranger requires three columns: mtry, splitrule, and min.node.size
  • Use expand.grid() to create all combinations of parameter values
  • Classification uses "gini" or "extratrees" splitrule; regression uses "variance", "extratrees", or "maxstat"
  • Extra arguments (num.trees, importance) are passed directly to ranger::ranger()
  • Use tuneLength for quick exploration and tuneGrid for systematic hyperparameter search
  • Always set set.seed() before training for reproducibility

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.