Orchestrate the supervised ssel workflow
modelPipeline.RdCompose split construction, fitting, evaluation, residual-offset and optimism audits, response-level selection, and final aggregation. This function is filesystem orchestration around public helpers; it is not a separate statistical estimator and it does not read a project manifest.
Usage
modelPipeline(
.path.datasets,
.path.train,
.path.model,
.path.metrics,
.path.response,
.path.summary,
.path.export,
.path.iter = NULL,
key,
responses,
datasets,
colsId = character(0),
features = NULL,
setCol = "set",
methods = c("ranger", "earth", "gbm"),
seed = NULL,
ensemble = "ensemble.RMSE",
boundsMin = -Inf,
boundsMax = Inf,
iterSuffix = NULL,
mode = "full",
responsesActive = NULL,
wipe = NULL,
shadow = FALSE
)Arguments
- .path.datasets
Existing directory of assembled CSV files. Every non-recursive filename ending in
.csvis processed bybuildDataset(), whether or not its basename occurs indatasets.- .path.train, .path.model, .path.metrics, .path.response, .path.summary, .path.export
Output directories for splits, fitted models, cell metrics, cell response predictions, summary products, and final exports. Missing directories are created recursively after any configured wipe. See Wipe and cache policy for destructive behavior.
- .path.iter
NULL, or an iteration directory. When supplied,aggregateResponses()writes or updatesY.csvthere for a later chain iteration.- key
A non-empty character key name passed to
buildDataset()andaggregateResponses(). Final response aggregation currently requires a column namedSampleIDindependently of this argument.- responses
Non-empty character vector of assembled response-column names. Names are inserted unescaped into regular expressions used for split and model discovery.
- datasets
Non-empty character vector of assembled dataset basenames used only by final
aggregateResponses()feature extraction. Among these declared files, the last one that exists suppliesX.csvandXo.csv. This vector does not restrict upstream split construction, fitting, OOF reconstruction, or prediction.- colsId
Character vector of additional identifier columns excluded from inferred predictors.
- features
NULL, or exact base predictor names passed tobuildDataset().NULLdelegates predictor inference to that helper.- setCol
Non-empty character name of the assembled row-role column, expected to distinguish
"train"and"predict".- methods
Character vector of fitted caret method identifiers. The default is
c("ranger", "earth", "gbm").- seed
NULL, or a value passed toset.seed()before split construction in every mode. It controls fitting/resampling and other downstream random operations only to the extent documented by each helper.- ensemble
Forwarded without initial validation to
predictModel(). That helper later requires one of"ensemble.RMSE"or"ensemble.R2"for its response-level selector. FinalaggregateResponses()output nevertheless always usesensemble.RMSEcandidates.- boundsMin, boundsMax
Numeric response bounds forwarded through OOF, point-prediction, audit, and aggregation paths. Their order and finiteness are not validated.
- iterSuffix
NULL, or the suffix identifying prior-iteration response features inbuildDataset(), commonly".o".- mode
A value in
c("full", "train", "predict").- responsesActive
NULL, or a value used without subset or type validation to filter fitting, OOF/audit reconstruction, and prediction.NULLusesresponses. Allresponsesare still split and passed to final aggregation. See Partial-response state.- wipe
NULL, or any value.NULLand the literal logical scalarTRUEenable wiping; every other value disables it throughisTRUE(). See Wipe and cache policy.- shadow
Logical value passed to
buildDataset()to add its Gaussian shadow predictor.
Value
Invisibly, NULL. Results are the files produced by the
selected mode and its composed helper calls.
Mode composition
Initial validation checks the type/non-emptiness conditions shown for
key, responses, datasets, setCol, and
non-null features, plus membership of mode. It does not
validate responsesActive, methods, ensemble,
wipe, shadow, or the response bounds. A non-null seed is
passed directly to set.seed(). Other conditions are delegated to the
called helpers and can therefore fail after destructive or expensive work.
Every mode prepares directories and calls buildDataset(), which scans
every CSV in .path.datasets. The response-column expression is the
unescaped anchored alternation ^(r1|r2|...)$, applied
case-insensitively. Fitting and prediction then discover dataset identifiers
independently from the generated split filenames. Active response filtering
of those names is exact and case-sensitive; the OOF and overfit model-file
parsers receive an unescaped, unanchored active-response alternation inside
their case-sensitive regular expressions.
"train"then callstrainModel()for active responses and stops. No OOF audit, prediction, overfit audit, or aggregation runs."predict"skips fitting, then callsauditQuantiles(),predictModel(),auditOverfit(), andaggregateResponses()in that order. Existing compatible models are therefore required."full"performs the training call followed by the complete prediction sequence above.
The offset audit must precede prediction because prediction consumes
prediction_quantiles.csv. Aggregation then consumes unadjusted long
point predictions, OOF residual rows, metric rows, and offsets. The overfit
audit is diagnostic; aggregation does not use overfit.csv. In
particular, ensemble is first checked when predictModel() starts:
after wiping, split construction, and the offset audit in prediction mode,
and additionally after fitting in full mode. An invalid value can therefore
leave partial products before it errors.
Wipe and cache policy
With wipe = NULL or true, the function recursively removes and
recreates .path.train, .path.metrics, .path.response,
and .path.summary in every mode. In "full" mode only, it also
recursively removes .path.model and .path.export; this same
condition sets OVERRIDE = TRUE for fitting. These operations are
destructive and have no rollback.
In "train" or "predict" mode, wiping preserves existing model
and export directories. Training mode then uses OVERRIDE = FALSE, so
surviving models can be reused under trainModel()'s predictor-name-only
cache rule. With wipe = FALSE, every existing output is preserved,
missing directories are created, and full-mode fitting also uses
OVERRIDE = FALSE. Current metric, residual, export, and iteration
helpers then apply their own merge or overwrite rules.
Products, selectors, and state
Every mode can overwrite split files. Train mode can additionally write
fitted model and hash files, then returns without summary or delivery calls.
Prediction mode never fits or writes model/hash files; it can write cell
metrics and responses, metrics.csv, response_long.csv,
residuals_oof.csv, prediction_quantiles.csv,
overfit.csv, Yo.csv, X.csv, Xo.csv, optional
Y.csv, and dataset-named intermediate exports. Full mode can write
all train- and prediction-mode products.
The ensemble argument governs only predictModel()'s per-response
dataset selector. aggregateResponses() independently forms its final
rowwise selection from ensemble.RMSE candidates and cell R2. These
selectors must not be described as one common "best model" rule.
Supplying seed changes the caller's RNG state. Both fitting and the
evaluation engine invoked by predictModel() register a bounded PSOCK
backend and leave foreach sequential under their accepted contracts.
Shadow generation and prediction method randomization have their documented
RNG effects. Errors and partial files from any helper propagate;
orchestration is not transactional.
Partial-response state
With a non-null responsesActive, the helpers do not follow one common
accumulation rule. auditQuantiles() replaces residual rows for active
responses in an existing residuals_oof.csv and regenerates offsets
from the merged residual table. predictModel() overwrites
response_long.csv with current active-response predictions; its
metrics.csv is the union of every cell-metric CSV currently present.
auditOverfit() overwrites overfit.csv from models matching the
active-response expression. aggregateResponses() preserves old
Yo.csv rows only for responses absent from the current unseen result,
and optional Y.csv preserves old non-overlapping response columns;
both use their own replacement rules. X.csv and Xo.csv are
overwritten from the last existing declared dataset. Thus
wipe = FALSE preserves inputs for mixed accumulation but does not
make every summary cumulative.
See also
buildDataset() for assembled input, trainModel() for fitting,
predictModel() for the first selector, and aggregateResponses() for
final delivery.
Examples
# \donttest{
root <- tempfile("ssel-pipeline-")
datasets_dir <- file.path(root, "datasets")
dir.create(datasets_dir, recursive = TRUE)
assembled <- data.frame(
SampleID = c(paste0("S", 1:16), "P1", "P2"),
set = c(rep("train", 16), "predict", "predict"),
x = 1:18,
z = rep(c(0, 1), 9),
target = c(1:16 / 3 + rep(c(-0.5, 0.5), 8), NA, NA)
)
utils::write.csv(
assembled,
file.path(datasets_dir, "demo.csv"),
row.names = FALSE,
na = ""
)
old_quiet <- getOption("aR.quiet")
options(aR.quiet = TRUE)
modelPipeline(
.path.datasets = datasets_dir,
.path.train = file.path(root, "train"),
.path.model = file.path(root, "model"),
.path.metrics = file.path(root, "metrics"),
.path.response = file.path(root, "response"),
.path.summary = file.path(root, "summary"),
.path.export = file.path(root, "export"),
key = "SampleID",
responses = "target",
datasets = "demo",
methods = "lm",
seed = 2026,
ensemble = "ensemble.RMSE",
mode = "full"
)
options(aR.quiet = old_quiet)
sort(basename(list.files(file.path(root, "summary"))))
#> [1] "metrics.csv" "overfit.csv"
#> [3] "prediction_quantiles.csv" "residuals_oof.csv"
#> [5] "response_long.csv"
data.table::fread(file.path(root, "export", "Yo.csv"))
#> SampleID response p value r2 dataset
#> <char> <char> <num> <num> <int> <char>
#> 1: P1 target 0.50 5.166667 1 demo
#> 2: P2 target 0.50 6.500000 1 demo
#> 3: P1 target 0.90 5.166667 1 demo
#> 4: P2 target 0.90 6.500000 1 demo
#> 5: P1 target 0.95 5.166667 1 demo
#> 6: P2 target 0.95 6.500000 1 demo
unlink(root, recursive = TRUE)
# }