| Title: | Automated Machine Learning and AI Agent Tools for Clinical Prediction Modelling |
|---|---|
| Description: | Provides a streamlined workflow for building, validating, and reporting clinical prediction models. Combines standard machine learning tools with an optional AI agent that recommends appropriate statistical methods, runs sensitivity analyses, and flags common pitfalls. Includes automated generation of reports aligned with TRIPOD+AI reporting guidance (Collins et al. (2024 <doi:10.1136/bmj-2023-078378>)) for reproducible, guideline-aligned research. |
| Authors: | Uwakmfon Paul [aut, cre, cph] |
| Maintainer: | Uwakmfon Paul <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.0 |
| Built: | 2026-10-05 07:42:22 UTC |
| Source: | https://github.com/devwebwacky/triager |
Runs a series of rule-based checks for common clinical-ML pitfalls
(class imbalance or low event rate, low events-per-variable, possible
leakage, near-zero variance predictors), then optionally asks an LLM to
summarize the findings in plain language. Works with both binary
classification models (triageR_model) and survival models
(triageR_survival_model).
tr_agent_review(data, model, use_agent = TRUE)tr_agent_review(data, model, use_agent = TRUE)
data |
The data frame used to fit the model. |
model |
A fitted |
use_agent |
Logical. If |
A triageR_review object (list) containing a tibble of flags
and, if use_agent = TRUE, an AI-generated summary.
## Not run: tr_agent_review(data, model) ## End(Not run)## Not run: tr_agent_review(data, model) ## End(Not run)
Produces a summary table of missingness per column, plus a visual plot showing the pattern of missing data across the dataset.
tr_check_missing(data)tr_check_missing(data)
data |
A data frame, typically the output of |
Invisibly returns a summary tibble (columns, n_missing, pct_missing). Also prints a summary to console and displays a missingness plot as a side effect.
df <- data.frame(a = c(1, NA, 3), b = c(4, 5, NA)) tr_check_missing(df)df <- data.frame(a = c(1, NA, 3), b = c(4, 5, NA)) tr_check_missing(df)
Generates variable importance or prediction explanations for a fitted
triageR_model, using the DALEX framework under the hood.
tr_explain( model, method = c("permutation", "shap"), newdata = NULL, observation = 1 )tr_explain( model, method = c("permutation", "shap"), newdata = NULL, observation = 1 )
model |
A fitted |
method |
Character. One of |
newdata |
Optional data frame to explain predictions on. If |
observation |
Integer. Row index of the observation to explain,
only used when |
A triageR_explanation object (list) containing the explanation
result and a plot.
## Not run: tr_explain(model, method = "permutation") tr_explain(model, method = "shap", observation = 3) ## End(Not run)## Not run: tr_explain(model, method = "permutation") tr_explain(model, method = "shap", observation = 3) ## End(Not run)
Fits a binary classification model using the parsnip/workflows
framework. The user must specify the model engine explicitly.
tr_fit( data, outcome, engine = c("logistic_reg", "random_forest", "boost_tree"), predictors = NULL )tr_fit( data, outcome, engine = c("logistic_reg", "random_forest", "boost_tree"), predictors = NULL )
data |
A data frame containing predictors and the outcome column. |
outcome |
Character. Name of the binary outcome column (must be a factor or coercible to one, with the event of interest as the second level). |
engine |
Character. Model engine to use. One of |
predictors |
Character vector of predictor column names. If |
A fitted triageR_model object — a list containing the fitted
workflow, the engine used, and the outcome/predictor names.
set.seed(1) df <- data.frame( age = round(rnorm(50, 55, 12)), sex = sample(c("M", "F"), 50, replace = TRUE), disease = sample(c(0, 1), 50, replace = TRUE) ) model <- tr_fit(df, outcome = "disease", engine = "logistic_reg")set.seed(1) df <- data.frame( age = round(rnorm(50, 55, 12)), sex = sample(c("M", "F"), 50, replace = TRUE), disease = sample(c(0, 1), 50, replace = TRUE) ) model <- tr_fit(df, outcome = "disease", engine = "logistic_reg")
censored/parsnip framework. The
outcome must be specified as separate time and event columns (following
survival::Surv() convention), and the user must explicitly choose an
engine.Fits a survival model using the censored/parsnip framework. The
outcome must be specified as separate time and event columns (following
survival::Surv() convention), and the user must explicitly choose an
engine.
tr_fit_survival( data, time_col, event_col, engine = c("cox_ph", "survival_rf"), predictors = NULL )tr_fit_survival( data, time_col, event_col, engine = c("cox_ph", "survival_rf"), predictors = NULL )
data |
A data frame containing predictors, a time column, and an event column. |
time_col |
Character. Name of the column giving time to event or censoring. |
event_col |
Character. Name of the column indicating event status (1 = event occurred, 0 = censored), following standard survival analysis convention. |
engine |
Character. One of |
predictors |
Character vector of predictor column names. If |
A fitted triageR_survival_model object (list) containing the
fitted workflow, engine, and time/event/predictor column names.
if (requireNamespace("survival", quietly = TRUE)) { library(survival) lung_clean <- lung lung_clean$status <- lung_clean$status - 1 # convert 1/2 to 0/1 lung_clean <- lung_clean[stats::complete.cases(lung_clean), ] model <- tr_fit_survival(lung_clean, time_col = "time", event_col = "status", engine = "cox_ph") }if (requireNamespace("survival", quietly = TRUE)) { library(survival) lung_clean <- lung lung_clean$status <- lung_clean$status - 1 # convert 1/2 to 0/1 lung_clean <- lung_clean[stats::complete.cases(lung_clean), ] model <- tr_fit_survival(lung_clean, time_col = "time", event_col = "status", engine = "cox_ph") }
Fills in missing values using either multiple imputation (mice) or
a random-forest based approach (missForest). The method must be
chosen explicitly, this function does not guess for you.
tr_impute(data, method = c("mice", "missForest"), m = 5, seed = 123)tr_impute(data, method = c("mice", "missForest"), m = 5, seed = 123)
data |
A data frame with missing values, typically the output of
|
method |
Character. Either |
m |
Integer. Number of multiple imputations to run if |
seed |
Integer. Random seed for reproducibility. Defaults to 123. |
A completed data frame with missing values filled in. If
method = "mice", the first completed dataset is returned, and the
full mids object is attached as an attribute ("mice_object") in
case the user wants to inspect all imputations.
df <- data.frame( a = c(5, 7, 3, 9, 2, 8, 6, 4, 5, 7), b = c(1, 3, 2, 4, 5, 3, 2, NA, 1, 3) ) completed <- tr_impute(df, method = "mice", m = 2)df <- data.frame( a = c(5, 7, 3, 9, 2, 8, 6, 4, 5, 7), b = c(1, 3, 2, 4, 5, 3, 2, NA, 1, 3) ) completed <- tr_impute(df, method = "mice", m = 2)
Opens an interactive Shiny application for building, validating, and
reporting clinical prediction models without writing R code directly.
Supports data upload, model fitting across multiple engines, validation,
explainability, automated pipeline review, and TRIPOD+AI report
generation. The AI method-recommendation feature requires a configured
Gemini API key (see ?tr_recommend_method) and is optional.
tr_launch_app()tr_launch_app()
Does not return; launches a Shiny application.
if (interactive()) { tr_launch_app() }if (interactive()) { tr_launch_app() }
Reads a flat clinical dataset (CSV or data frame) and returns it as a
standardized triageR object with basic structure checks. This is the
entry point for most triageR workflows.
tr_load_clinical(data, id_col = "id")tr_load_clinical(data, id_col = "id")
data |
A file path to a CSV, or an existing data frame. |
id_col |
Character. Name of the column identifying unique patients.
Defaults to |
A tibble of class triageR_data, with basic metadata attached.
df <- data.frame( id = 1:5, age = c(45, 62, 38, 71, 55), sex = c("F", "M", "F", "M", "F") ) tr_load_clinical(df, id_col = "id")df <- data.frame( id = 1:5, age = c(45, 62, 38, 71, 55), sex = c("F", "M", "F", "M", "F") ) tr_load_clinical(df, id_col = "id")
Uses an LLM to inspect the structure of a clinical dataset and suggest an appropriate statistical or machine learning approach, with reasoning. This is an assistive tool, not a replacement for expert judgment.
tr_recommend_method(data, outcome, context = NULL)tr_recommend_method(data, outcome, context = NULL)
data |
A data frame, typically the output of |
outcome |
Character. Name of the outcome column of interest. |
context |
Optional character string giving extra clinical context (e.g. "predicting 30-day readmission in heart failure patients"). |
Invisibly returns the raw text recommendation (character string). Also prints the recommendation to console.
## Not run: tr_recommend_method(data, outcome = "disease", context = "predicting diabetes onset in adults") ## End(Not run)## Not run: tr_recommend_method(data, outcome = "disease", context = "predicting diabetes onset in adults") ## End(Not run)
Re-fits a clinical prediction model under several robustness checks, complete-case vs imputed data, outlier exclusion, and subgroup consistency, and compares performance metrics across them.
tr_sensitivity(data, model, subgroup_col = NULL, outlier_sd = 3)tr_sensitivity(data, model, subgroup_col = NULL, outlier_sd = 3)
data |
The original (pre-imputation) data frame, containing the
same predictors and outcome used in |
model |
A fitted |
subgroup_col |
Optional character. Name of a categorical column (e.g. "sex") to check subgroup consistency across. |
outlier_sd |
Numeric. Number of standard deviations beyond which a numeric predictor value is considered an outlier and excluded in the outlier-robustness check. Defaults to 3. |
A triageR_sensitivity object (list) with a comparison tibble
of metrics across all sensitivity scenarios.
## Not run: tr_sensitivity(data, model, subgroup_col = "sex") ## End(Not run)## Not run: tr_sensitivity(data, model, subgroup_col = "sex") ## End(Not run)
Renders a reproducible report summarizing model fit, validation, sensitivity analysis, and pipeline review, aligned with TRIPOD+AI reporting guidance. Supports both binary classification and survival models. This is a drafting aid, not a certified compliance tool.
tr_tripod_report( model, model_type = c("classification", "survival"), validation = NULL, review = NULL, sensitivity = NULL, recommendation = NULL, output_file = file.path(tempdir(), "triageR_report"), format = c("html", "docx") )tr_tripod_report( model, model_type = c("classification", "survival"), validation = NULL, review = NULL, sensitivity = NULL, recommendation = NULL, output_file = file.path(tempdir(), "triageR_report"), format = c("html", "docx") )
model |
A fitted |
model_type |
Character. Either |
validation |
Optional validation object: a |
review |
Optional |
sensitivity |
Optional |
recommendation |
Optional character string from |
output_file |
Character. File path (without extension) to save the
report to. Defaults to a file in |
format |
Character. Either |
Invisibly returns the path to the rendered report file.
## Not run: tr_tripod_report(model, validation = val, review = rev, output_file = file.path(tempdir(), "report")) ## End(Not run)## Not run: tr_tripod_report(model, validation = val, review = rev, output_file = file.path(tempdir(), "report")) ## End(Not run)
Computes discrimination (AUC, sensitivity, specificity) and calibration
metrics for a fitted triageR_model. Can validate on new (external/holdout)
data, or fall back to the training data with a clear warning.
tr_validate( model, newdata = NULL, threshold = 0.5, calibration_method = c("binned", "smooth") )tr_validate( model, newdata = NULL, threshold = 0.5, calibration_method = c("binned", "smooth") )
model |
A fitted |
newdata |
Optional data frame to validate on. If |
threshold |
Numeric. Probability threshold for classifying the positive class. Defaults to 0.5. |
calibration_method |
Character. One of |
A triageR_validation object (list) containing a metrics tibble
and the underlying predictions, invisibly printed as a summary.
set.seed(1) df <- data.frame( age = round(rnorm(50, 55, 12)), sex = sample(c("M", "F"), 50, replace = TRUE), disease = sample(c(0, 1), 50, replace = TRUE) ) model <- tr_fit(df, outcome = "disease", engine = "logistic_reg") tr_validate(model, newdata = df)set.seed(1) df <- data.frame( age = round(rnorm(50, 55, 12)), sex = sample(c("M", "F"), 50, replace = TRUE), disease = sample(c(0, 1), 50, replace = TRUE) ) model <- tr_fit(df, outcome = "disease", engine = "logistic_reg") tr_validate(model, newdata = df)
Computes the concordance index (C-index) for a fitted
triageR_survival_model — the survival-analysis equivalent of AUC,
measuring how well the model ranks patients by risk. Can validate on
new (external/holdout) data, or fall back to the training data with a
clear warning.
tr_validate_survival(model, newdata = NULL)tr_validate_survival(model, newdata = NULL)
model |
A fitted |
newdata |
Optional data frame to validate on. If |
A triageR_survival_validation object (list) containing the
C-index and supporting details.
if (requireNamespace("survival", quietly = TRUE)) { library(survival) lung_clean <- lung lung_clean$status <- lung_clean$status - 1 lung_clean <- lung_clean[stats::complete.cases(lung_clean), ] model <- tr_fit_survival(lung_clean, time_col = "time", event_col = "status", engine = "cox_ph") tr_validate_survival(model, newdata = lung_clean) }if (requireNamespace("survival", quietly = TRUE)) { library(survival) lung_clean <- lung lung_clean$status <- lung_clean$status - 1 lung_clean <- lung_clean[stats::complete.cases(lung_clean), ] model <- tr_fit_survival(lung_clean, time_col = "time", event_col = "status", engine = "cox_ph") tr_validate_survival(model, newdata = lung_clean) }