library(mlr3verse)Scope
This is the second part of the practical tuning series. The other parts can be found here:
- Part I - Tune a Support Vector Machine
- Part III - Build an Automated Machine Learning System
- Part IV - Tuning and Parallel Processing
In this post, we build a simple preprocessing pipeline and tune it. For this, we are using the mlr3pipelines extension package. First, we start by imputing missing values in the diabetes data set. After that, we encode a factor column to numerical dummy columns in the data set. Next, we combine both preprocessing steps to a Graph and create a GraphLearner. Finally, nested resampling is used to compare the performance of two imputation methods.
Prerequisites
We load the mlr3verse package which pulls in the most important packages for this example.
We initialize the random number generator with a fixed seed for reproducibility, and decrease the verbosity of the logger to keep the output clearly represented. The lgr package is used for logging in all mlr3 packages. The mlr3 logger prints the logging messages from the base package, whereas the bbotk logger is responsible for logging messages from the optimization packages (e.g. mlr3tuning ).
set.seed(7832)
lgr::get_logger("mlr3")$set_threshold("warn")
lgr::get_logger("bbotk")$set_threshold("warn")In this example, we use the diabetes data set which is used to predict whether or not a patient has diabetes. The patients are characterized by 8 numeric features of which some have missing values. We alter the data set by categorizing the feature pressure (blood pressure) into the categories "low", "mid", and "high".
# retrieve the task from mlr3
task = tsk("diabetes")
# create data frame with categorized pressure feature
data = task$data(cols = "pressure")
breaks = quantile(data$pressure, probs = c(0, 0.33, 0.66, 1), na.rm = TRUE)
data$pressure = cut(data$pressure, breaks, labels = c("low", "mid", "high"))
# overwrite the feature in the task
task$cbind(data)
# generate a quick textual overview
skimr::skim(task$data())| Name | task$data() |
| Number of rows | 128 |
| Number of columns | 9 |
| Key | NULL |
| _______________________ | |
| Column type frequency: | |
| factor | 2 |
| numeric | 7 |
| ________________________ | |
| Group variables | None |
Variable type: factor
| skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
|---|---|---|---|---|---|
| diabetes | 0 | 1.00 | FALSE | 2 | neg: 83, pos: 45 |
| pressure | 7 | 0.95 | FALSE | 3 | low: 41, hig: 41, mid: 39 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| age | 0 | 1.00 | 34.48 | 3.29 | 24.00 | 32.00 | 34.00 | 37.00 | 44.00 | ▁▅▇▅▁ |
| glucose | 6 | 0.95 | 121.61 | 24.45 | 64.00 | 104.50 | 121.00 | 137.00 | 176.00 | ▁▅▇▆▂ |
| insulin | 5 | 0.96 | 101.79 | 77.29 | 14.00 | 57.00 | 82.00 | 125.50 | 598.00 | ▇▂▁▁▁ |
| mass | 5 | 0.96 | 32.00 | 5.52 | 19.80 | 28.45 | 32.10 | 35.40 | 45.70 | ▂▆▇▃▂ |
| pedigree | 0 | 1.00 | 0.48 | 0.40 | 0.04 | 0.22 | 0.34 | 0.65 | 2.18 | ▇▃▁▁▁ |
| pregnant | 0 | 1.00 | 3.83 | 1.85 | 0.00 | 2.00 | 4.00 | 5.00 | 8.00 | ▂▇▅▅▂ |
| triceps | 5 | 0.96 | 25.17 | 8.68 | 5.00 | 19.00 | 26.00 | 30.00 | 49.00 | ▂▆▇▃▁ |
We choose the xgboost algorithm from the xgboost package as learner.
learner = lrn("classif.xgboost", nrounds = 100, id = "xgboost", verbose = 0)Missing Values
The task has missing data in five columns.
round(task$missings() / task$nrow, 2)diabetes age glucose insulin mass pedigree pregnant pressure triceps
0.00 0.00 0.05 0.04 0.04 0.00 0.00 0.05 0.04
The xgboost learner has an internal method for handling missing data but some learners cannot handle missing values. We will try to beat the internal method in terms of predictive performance. The mlr3pipelines package offers various methods to impute missing values.
mlr_pipeops$keys("^impute")[1] "imputeconstant" "imputehist" "imputelearner" "imputemean" "imputemedian" "imputemode"
[7] "imputeoor" "imputesample"
We choose the PipeOpImputeOOR that adds the new factor level ".MISSING". to factorial features and imputes numerical features by constant values shifted below the minimum (default) or above the maximum.
imputer = po("imputeoor")
print(imputer)
── PipeOp <imputeoor>: not trained ─────────────────────────────────────────────────────────────────────────────────────
Values: min=TRUE, offset=1, multiplier=1, create_empty_level=FALSE
── Input channels:
name train predict
<char> <char> <char>
input Task Task
── Output channels:
name train predict
<char> <char> <char>
output Task Task
As the output suggests, the in- and output of this pipe operator is a Task for both the training and the predict step. We can manually train the pipe operator to check its functionality:
task_imputed = imputer$train(list(task))[[1]]
task_imputed$missings()diabetes age pedigree pregnant glucose insulin mass pressure triceps
0 0 0 0 0 0 0 0 0
Let’s compare an observation with missing values to the observation with imputed observation.
rbind(
task$data()[1,],
task_imputed$data()[1,]
) diabetes age glucose insulin mass pedigree pregnant pressure triceps
<fctr> <int> <num> <num> <num> <num> <int> <fctr> <num>
1: pos 38 NA 15 21.9 0.106 4 high 30
2: pos 38 -49 15 21.9 0.106 4 high 30
Note that OOR imputation is in particular useful for tree-based models, but should not be used for linear models or distance-based models.
Factor Encoding
The xgboost learner cannot handle categorical features. Therefore, we must to convert factor columns to numerical dummy columns. For this, we argument the xgboost learner with automatic factor encoding.
The PipeOpEncode encodes factor columns with one of six methods. In this example, we use one-hot encoding which creates a new binary column for each factor level.
factor_encoding = po("encode", method = "one-hot")We manually trigger the encoding on the task.
factor_encoding$train(list(task))$output
── <TaskClassif> (128x11): Synthetic Diabetes ──────────────────────────────────────────────────────────────────────────
• Target: diabetes
• Properties: twoclass
• Features (10):
• dbl (8): glucose, insulin, mass, pedigree, pressure.high, pressure.low, pressure.mid, triceps
• int (2): age, pregnant
• Target classes: pos (positive class, 35%), neg (65%)
The factor column pressure has been converted to the three binary columns "pressure.low", "pressure.mid", and "pressure.high".
Constructing the Pipeline
We created two preprocessing steps which could be used to create a new task with encoded factor variables and imputed missing values. However, if we do this before resampling, information from the test can leak into our training step which typically leads to overoptimistic performance measures. To avoid this, we add the preprocessing steps to the Learner itself, creating a GraphLearner. For this, we create a Graph first.
graph = po("encode") %>>%
po("imputeoor") %>>%
learner
plot(graph, html = FALSE)
We use as_learner() to wrap the Graph into a GraphLearner with which allows us to use the graph like a normal learner.
graph_learner = as_learner(graph)
# short learner id for printing
graph_learner$id = "graph_learner"The GraphLearner can be trained and used for making predictions. Instead of calling $train() or $predict() manually, we will directly use it for resampling. We choose a 3-fold cross-validation as the resampling strategy.
resampling = rsmp("cv", folds = 3)
rr = resample(task = task, learner = graph_learner, resampling = resampling)rr$score()[, c("iteration", "task_id", "learner_id", "resampling_id", "classif.ce"), with = FALSE] iteration task_id learner_id resampling_id classif.ce
<int> <char> <char> <char> <num>
1: 1 diabetes graph_learner cv 0.3255814
2: 2 diabetes graph_learner cv 0.4186047
3: 3 diabetes graph_learner cv 0.4047619
For each resampling iteration, the following steps are performed:
- The task is subsetted to the training indices.
- The factor encoder replaces factor features with dummy columns in the training task.
- The OOR imputer determines values to impute from the training task and then replaces all missing values with learned imputation values.
- The learner is applied on the modified training task and the model is stored inside the learner.
Next is the predict step:
- The task is subsetted to the test indices.
- The factor encoder replaces all factor features with dummy columns in the test task.
- The OOR imputer replaces all missing values of the test task with the imputation values learned on the training set.
- The learner’s predict method is applied on the modified test task.
By following this procedure, it is guaranteed that no information can leak from the training step to the predict step.
Tuning the Pipeline
Let’s have a look at the parameter set of the GraphLearner. It consists of the xgboost hyperparameters, and additionally, the parameter of the PipeOp encode and imputeoor. All hyperparameters are prefixed with the id of the respective PipeOp or learner.
as.data.table(graph_learner$param_set)[, c("id", "class", "lower", "upper", "nlevels"), with = FALSE] id class lower upper nlevels
<char> <char> <num> <num> <num>
1: encode.method ParamFct NA NA 5
2: encode.affect_columns ParamUty NA NA Inf
3: imputeoor.min ParamLgl NA NA 2
4: imputeoor.offset ParamDbl 0 Inf Inf
5: imputeoor.multiplier ParamDbl 0 Inf Inf
6: imputeoor.affect_columns ParamUty NA NA Inf
7: imputeoor.create_empty_level ParamLgl NA NA 2
8: xgboost.alpha ParamDbl 0 Inf Inf
9: xgboost.approxcontrib ParamLgl NA NA 2
10: xgboost.base_score ParamDbl -Inf Inf Inf
11: xgboost.booster ParamFct NA NA 3
12: xgboost.callbacks ParamUty NA NA Inf
13: xgboost.colsample_bylevel ParamDbl 0 1 Inf
14: xgboost.colsample_bynode ParamDbl 0 1 Inf
15: xgboost.colsample_bytree ParamDbl 0 1 Inf
16: xgboost.device ParamUty NA NA Inf
17: xgboost.disable_default_eval_metric ParamLgl NA NA 2
18: xgboost.early_stopping_rounds ParamInt 1 Inf Inf
19: xgboost.eta ParamDbl 0 1 Inf
20: xgboost.evals ParamUty NA NA Inf
21: xgboost.eval_metric ParamUty NA NA Inf
22: xgboost.custom_metric ParamUty NA NA Inf
23: xgboost.feature_selector ParamFct NA NA 5
24: xgboost.gamma ParamDbl 0 Inf Inf
25: xgboost.grow_policy ParamFct NA NA 2
26: xgboost.interaction_constraints ParamUty NA NA Inf
27: xgboost.iterationrange ParamUty NA NA Inf
28: xgboost.lambda ParamDbl 0 Inf Inf
29: xgboost.max_bin ParamInt 2 Inf Inf
30: xgboost.max_cached_hist_node ParamInt -Inf Inf Inf
31: xgboost.max_cat_to_onehot ParamInt -Inf Inf Inf
32: xgboost.max_cat_threshold ParamDbl -Inf Inf Inf
33: xgboost.max_delta_step ParamDbl 0 Inf Inf
34: xgboost.max_depth ParamInt 0 Inf Inf
35: xgboost.max_leaves ParamInt 0 Inf Inf
36: xgboost.maximize ParamLgl NA NA 2
37: xgboost.min_child_weight ParamDbl 0 Inf Inf
38: xgboost.missing ParamDbl -Inf Inf Inf
39: xgboost.monotone_constraints ParamUty NA NA Inf
40: xgboost.nrounds ParamInt 1 Inf Inf
41: xgboost.normalize_type ParamFct NA NA 2
42: xgboost.nthread ParamInt 1 Inf Inf
43: xgboost.num_parallel_tree ParamInt 1 Inf Inf
44: xgboost.objective ParamUty NA NA Inf
45: xgboost.one_drop ParamLgl NA NA 2
46: xgboost.print_every_n ParamInt 1 Inf Inf
47: xgboost.rate_drop ParamDbl 0 1 Inf
48: xgboost.refresh_leaf ParamLgl NA NA 2
49: xgboost.seed ParamInt -Inf Inf Inf
50: xgboost.seed_per_iteration ParamLgl NA NA 2
51: xgboost.sampling_method ParamFct NA NA 2
52: xgboost.sample_type ParamFct NA NA 2
53: xgboost.save_name ParamUty NA NA Inf
54: xgboost.save_period ParamInt 0 Inf Inf
55: xgboost.scale_pos_weight ParamDbl -Inf Inf Inf
56: xgboost.skip_drop ParamDbl 0 1 Inf
57: xgboost.subsample ParamDbl 0 1 Inf
58: xgboost.top_k ParamInt 0 Inf Inf
59: xgboost.training ParamLgl NA NA 2
60: xgboost.tree_method ParamFct NA NA 5
61: xgboost.tweedie_variance_power ParamDbl 1 2 Inf
62: xgboost.updater ParamUty NA NA Inf
63: xgboost.use_rmm ParamLgl NA NA 2
64: xgboost.validate_features ParamLgl NA NA 2
65: xgboost.verbose ParamInt 0 2 3
66: xgboost.verbosity ParamInt 0 2 3
67: xgboost.xgb_model ParamUty NA NA Inf
68: xgboost.use_pred_offset ParamLgl NA NA 2
id class lower upper nlevels
<char> <char> <num> <num> <num>
We will tune the encode method.
graph_learner$param_set$values$encode.method = to_tune(c("one-hot", "treatment"))We define a tuning instance and use grid search since we want to try all encode methods.
instance = tune(
tuner = tnr("grid_search"),
task = task,
learner = graph_learner,
resampling = rsmp("cv", folds = 3),
measure = msr("classif.ce")
)The archive shows us the performance of the model with different encoding methods.
print(instance$archive)
── <ArchiveBatchTuning> with 2 evaluations ─────────────────────────────────────────────────────────────────────────────
encode.method classif.ce warnings errors batch_nr
<char> <num> <int> <int> <int>
1: one-hot 0.41 0 0 1
2: treatment 0.42 0 0 2
Nested Resampling
We create one GraphLearner with imputeoor and test it against a GraphLearner that uses the internal imputation method of xgboost. Applying nested resampling ensures a fair comparison of the predictive performances.
graph_1 = po("encode") %>>%
learner
graph_learner_1 = GraphLearner$new(graph_1)
graph_learner_1$param_set$values$encode.method = to_tune(c("one-hot", "treatment"))
at_1 = auto_tuner(
learner = graph_learner_1,
resampling = resampling,
measure = msr("classif.ce"),
terminator = trm("none"),
tuner = tnr("grid_search"),
store_models = TRUE
)graph_2 = po("encode") %>>%
po("imputeoor") %>>%
learner
graph_learner_2 = GraphLearner$new(graph_2)
graph_learner_2$param_set$values$encode.method = to_tune(c("one-hot", "treatment"))
at_2 = auto_tuner(
learner = graph_learner_2,
resampling = resampling,
measure = msr("classif.ce"),
terminator = trm("none"),
tuner = tnr("grid_search"),
store_models = TRUE
)We run the benchmark.
resampling_outer = rsmp("cv", folds = 3)
design = benchmark_grid(task, list(at_1, at_2), resampling_outer)
bmr = benchmark(design, store_models = TRUE)We compare the aggregated performances on the outer test sets which give us an unbiased performance estimate of the GraphLearners with the different encoding methods.
bmr$aggregate() nr task_id learner_id resampling_id iters classif.ce
<int> <char> <char> <char> <int> <num>
1: 1 diabetes encode.xgboost.tuned cv 3 0.3826135
2: 2 diabetes encode.imputeoor.xgboost.tuned cv 3 0.3510520
Hidden columns: resample_result
autoplot(bmr)
Note that in practice, it is required to tune preprocessing hyperparameters jointly with the hyperparameters of the learner. Otherwise, comparing preprocessing steps is not feasible and can lead to wrong conclusions.
Applying nested resampling can be shortened by using the auto_tuner()-shortcut.
graph_1 = po("encode") %>>% learner
graph_learner_1 = as_learner(graph_1)
graph_learner_1$param_set$values$encode.method = to_tune(c("one-hot", "treatment"))
at_1 = auto_tuner(
method = "grid_search",
learner = graph_learner_1,
resampling = resampling,
measure = msr("classif.ce"),
store_models = TRUE)
graph_2 = po("encode") %>>% po("imputeoor") %>>% learner
graph_learner_2 = as_learner(graph_2)
graph_learner_2$param_set$values$encode.method = to_tune(c("one-hot", "treatment"))
at_2 = auto_tuner(
method = "grid_search",
learner = graph_learner_2,
resampling = resampling,
measure = msr("classif.ce"),
store_models = TRUE)
design = benchmark_grid(task, list(at_1, at_2), rsmp("cv", folds = 3))
bmr = benchmark(design, store_models = TRUE)Final Model
We train the chosen GraphLearner with the AutoTuner to get a final model with optimized hyperparameters.
at_2$train(task)The trained model can now be used to make predictions on new data at_2$predict(). The pipeline ensures that the preprocessing is always a part of the train and predict step.
Resources
The mlr3book includes chapters on pipelines and hyperparameter tuning. The mlr3cheatsheets contain frequently used commands and workflows of mlr3.
Session Information
sessioninfo::session_info(info = "packages")═ Session info ═══════════════════════════════════════════════════════════════════════════════════════════════════════
─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────
package * version date (UTC) lib source
backports 1.5.1 2026-04-03 [1] RSPM
base64enc 0.1-6 2026-02-02 [1] RSPM
base64url 1.4 2018-05-14 [1] RSPM
batchtools 0.9.18 2025-08-20 [1] RSPM
bbotk 1.12.0 2026-07-17 [1] RSPM
bit 4.6.0 2025-03-06 [1] RSPM
bit64 4.8.2 2026-05-19 [1] RSPM
brew 1.0-10 2023-12-16 [1] RSPM
callr 3.8.0 2026-06-05 [1] RSPM
checkmate 2.3.4 2026-02-03 [1] RSPM
class 7.3-23 2025-01-01 [2] CRAN (R 4.6.1)
classInt 0.4-11 2025-01-08 [1] RSPM
cli 3.6.6 2026-04-09 [1] RSPM
cluster 2.1.8.2 2026-02-05 [2] CRAN (R 4.6.1)
codetools 0.2-20 2024-03-31 [2] CRAN (R 4.6.1)
coro 1.1.0 2024-11-05 [1] RSPM
crayon 1.5.3 2024-06-20 [1] RSPM
data.table * 1.18.4 2026-05-06 [1] RSPM
DBI 1.3.0 2026-02-25 [1] RSPM
dictionar6 0.1.3 2026-02-23 [1] https://m~
digest 0.6.39 2025-11-19 [1] RSPM
distr6 1.8.4 2026-02-23 [1] https://m~
dplyr 1.2.1 2026-04-03 [1] RSPM
e1071 1.7-17 2025-12-18 [1] RSPM
evaluate 1.0.5 2025-08-27 [1] RSPM
farver 2.1.2 2024-05-13 [1] RSPM
fastmap 1.2.0 2024-05-15 [1] RSPM
future * 1.75.0 2026-07-20 [1] RSPM
future.apply 1.20.2 2026-02-20 [1] RSPM
generics 0.1.4 2025-05-09 [1] RSPM
ggplot2 4.0.3 2026-04-22 [1] RSPM
globals 0.19.1 2026-03-13 [1] RSPM
glue 1.8.1 2026-04-17 [1] RSPM
gtable 0.3.6 2024-10-25 [1] RSPM
hms 1.1.4 2025-10-17 [1] RSPM
htmltools 0.5.9 2025-12-04 [1] RSPM
htmlwidgets 1.6.4 2023-12-06 [1] RSPM
igraph 2.3.3 2026-06-26 [1] RSPM
jsonlite 2.0.0 2025-03-27 [1] RSPM
KernSmooth 2.23-26 2025-01-01 [2] CRAN (R 4.6.1)
knitr 1.51 2025-12-20 [1] RSPM
labeling 0.4.3 2023-08-29 [1] RSPM
lattice 0.22-9 2026-02-09 [2] CRAN (R 4.6.1)
lgr 0.5.2 2026-01-30 [1] RSPM
lifecycle 1.0.5 2026-01-08 [1] RSPM
listenv 1.0.0 2026-06-22 [1] RSPM
magrittr 2.0.5 2026-04-04 [1] RSPM
Matrix 1.7-5 2026-03-21 [2] CRAN (R 4.6.1)
matrixStats 1.5.0 2025-01-07 [1] RSPM
mgcv 1.9-4 2025-11-07 [2] CRAN (R 4.6.1)
mlr3 * 1.7.1.9000 2026-08-07 [1] Github (mlr-org/mlr3@c63e546)
mlr3batchmark 0.2.2 2025-09-04 [1] RSPM
mlr3benchmark 0.1.7-9000 2026-08-07 [1] Github (mlr-org/mlr3benchmark@771107a)
mlr3cluster * 0.4.1 2026-07-10 [1] RSPM
mlr3cmprsk 0.0.5 2026-04-11 [1] https://m~
mlr3data 0.9.0 2024-11-08 [1] RSPM
mlr3db 0.7.2 2026-05-22 [1] RSPM
mlr3extralearners 1.6.0 2026-07-14 [1] https://m~
mlr3fairness * 0.4.0 2026-08-07 [1] Github (mlr-org/mlr3fairness@6946cbe)
mlr3fda * 0.7.1 2026-07-15 [1] RSPM
mlr3filters 0.9.1 2026-04-23 [1] RSPM
mlr3fselect * 1.6.0.9000 2026-08-07 [1] Github (mlr-org/mlr3fselect@3bc9771)
mlr3hyperband 1.1.1 2026-07-25 [1] RSPM
mlr3inferr 0.2.1 2025-11-26 [1] RSPM
mlr3learners 0.15.1 2026-07-25 [1] RSPM
mlr3mbo 1.2.1 2026-07-26 [1] RSPM
mlr3measures 1.3.0 2026-04-17 [1] RSPM
mlr3misc 0.22.0 2026-06-10 [1] RSPM
mlr3oml 0.12.0 2026-01-28 [1] RSPM
mlr3pipelines * 0.11.0-9000 2026-08-07 [1] Github (mlr-org/mlr3pipelines@3a48115)
mlr3proba * 0.8.10 2026-06-05 [1] https://m~
mlr3spatial 0.7.0 2026-07-14 [1] RSPM
mlr3spatiotempcv 2.3.5 2026-08-03 [1] RSPM
mlr3torch * 0.3.3 2026-01-31 [1] RSPM
mlr3tuning 1.6.1 2026-07-26 [1] RSPM
mlr3tuningspaces 0.7.0 2026-07-25 [1] RSPM
mlr3verse * 0.3.2 2026-06-22 [1] RSPM
mlr3viz 0.11.1 2026-07-26 [1] RSPM
mlr3website * 0.0.0.9000 2026-08-07 [1] Github (mlr-org/mlr3website@83dce5a)
moocore 0.3.2 2026-07-12 [1] RSPM
nlme 3.1-169 2026-03-27 [2] CRAN (R 4.6.1)
ooplah 0.2.0 2022-03-25 [1] https://m~
otel 0.2.0 2025-08-29 [1] RSPM
palmerpenguins 0.1.1 2022-08-15 [1] RSPM
paradox 1.0.1 2024-07-09 [1] RSPM
parallelly 1.48.0 2026-06-29 [1] RSPM
param6 0.2.4 2026-02-23 [1] https://m~
pillar 1.11.1 2025-09-17 [1] RSPM
pkgconfig 2.0.3 2019-09-22 [1] RSPM
prettyunits 1.2.0 2023-09-24 [1] RSPM
processx 3.9.0 2026-04-22 [1] RSPM
progress 1.2.3 2023-12-06 [1] RSPM
proxy 0.4-29 2025-12-29 [1] RSPM
ps 1.9.3 2026-04-20 [1] RSPM
purrr 1.2.2 2026-04-10 [1] RSPM
R6 2.6.1 2025-02-15 [1] RSPM
rappdirs 0.3.4 2026-01-17 [1] RSPM
rbibutils 2.4.1 2026-01-21 [1] RSPM
RColorBrewer 1.1-3 2022-04-03 [1] RSPM
Rcpp 1.1.2 2026-07-05 [1] RSPM
Rdpack 2.6.6 2026-02-08 [1] RSPM
repr 1.1.7 2024-03-22 [1] RSPM
rlang 1.3.0 2026-07-05 [1] RSPM
rmarkdown 2.31 2026-03-26 [1] RSPM
S7 0.2.2 2026-04-22 [1] RSPM
scales 1.4.0 2025-04-24 [1] RSPM
sessioninfo 1.2.4 2026-06-04 [1] RSPM
set6 0.2.6 2026-02-23 [1] https://m~
sf 1.1-2 2026-07-23 [1] RSPM
skimr 2.2.2 2026-01-10 [1] RSPM
spacefillr 0.4.0 2025-02-24 [1] RSPM
stringi 1.8.9 2026-08-04 [1] RSPM
stringr 1.6.0 2025-11-04 [1] RSPM
survival 3.8-6 2026-01-16 [2] CRAN (R 4.6.1)
terra 1.9-34 2026-06-19 [1] RSPM
tf 0.5.0 2026-07-14 [1] RSPM
tibble 3.3.1 2026-01-11 [1] RSPM
tidyr 1.3.2 2025-12-19 [1] RSPM
tidyselect 1.2.1 2024-03-11 [1] RSPM
torch * 0.17.0 2026-04-11 [1] RSPM
units 1.0-1 2026-03-11 [1] RSPM
uuid 1.2-2 2026-01-23 [1] RSPM
vctrs 0.7.3 2026-04-11 [1] RSPM
viridisLite 0.4.3 2026-02-04 [1] RSPM
withr 3.0.3 2026-06-19 [1] RSPM
xfun 0.60 2026-07-09 [1] RSPM
xgboost 3.2.1.1 2026-03-18 [1] CRAN (R 4.6.1)
yaml 2.3.12 2025-12-10 [1] RSPM
zoo 1.9-0 2026-07-31 [1] RSPM
[1] /usr/local/lib/R/site-library
[2] /usr/local/lib/R/library
* ── Packages attached to the search path.
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────