--- title: "Introduction to triageR" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to triageR} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 4 ) ``` ```{r setup} library(triageR) library(mlbench) ``` ## Overview This vignette walks through a full clinical prediction modelling workflow using triageR, from raw data to a TRIPOD+AI-aligned report. We will use the **PIMA Indians Diabetes** dataset, a well-known real-world clinical dataset, to demonstrate each stage of the pipeline. ## 1. Load and prepare data The PIMA dataset has a known data quality issue: several clinical measurements use `0` to represent a missing value, which we know is physiologically impossible for variables like blood pressure or BMI. We convert these to proper `NA`s before proceeding, this is a good example of the kind of cleaning `tr_load_clinical()` expects to receive data after. ```{r} data(PimaIndiansDiabetes) pima <- PimaIndiansDiabetes pima$id <- seq_len(nrow(pima)) pima$glucose[pima$glucose == 0] <- NA pima$pressure[pima$pressure == 0] <- NA pima$triceps[pima$triceps == 0] <- NA pima$insulin[pima$insulin == 0] <- NA pima$mass[pima$mass == 0] <- NA pima_loaded <- tr_load_clinical(pima, id_col = "id") pima_loaded ``` ## 2. Check and handle missing data ```{r} tr_check_missing(pima_loaded) ``` `insulin` and `triceps` show substantial missingness — a realistic scenario in clinical datasets. We impute using `mice`: ```{r, message = FALSE, results = "hide"} pima_for_impute <- pima_loaded[, setdiff(names(pima_loaded), "id")] pima_imputed <- tr_impute(pima_for_impute, method = "mice", m = 5) ``` ```{r} sum(is.na(pima_imputed)) ``` ## 3. Fit a model We split the data into training and test sets, then fit a logistic regression model. ```{r} set.seed(42) n <- nrow(pima_imputed) train_idx <- sample(seq_len(n), size = floor(0.7 * n)) pima_train <- pima_imputed[train_idx, ] pima_test <- pima_imputed[-train_idx, ] pima_model <- tr_fit(pima_train, outcome = "diabetes", engine = "logistic_reg") ``` triageR also supports `"random_forest"` and `"boost_tree"` engines via the same interface — useful for comparing approaches without rewriting your pipeline: ```{r} pima_model_rf <- tr_fit(pima_train, outcome = "diabetes", engine = "random_forest") pima_model_xgb <- tr_fit(pima_train, outcome = "diabetes", engine = "boost_tree") ``` ## 4. Validate the model Validation on a genuine holdout set produces discrimination metrics, a confusion matrix, and an ROC curve. We validate all three engines on the same holdout set to compare performance. ```{r} pima_validation <- tr_validate(pima_model, newdata = pima_test) pima_validation_rf <- tr_validate(pima_model_rf, newdata = pima_test) pima_validation_xgb <- tr_validate(pima_model_xgb, newdata = pima_test) ``` ```{r} pima_validation$roc_plot ``` ### Comparing engines ```{r} engine_comparison <- dplyr::bind_rows( dplyr::mutate(pima_validation$metrics, engine = "logistic_reg"), dplyr::mutate(pima_validation_rf$metrics, engine = "random_forest"), dplyr::mutate(pima_validation_xgb$metrics, engine = "boost_tree") ) tidyr::pivot_wider(engine_comparison, names_from = .metric, values_from = .estimate) ``` ```{r} pima_validation_rf$roc_plot pima_validation_xgb$roc_plot ``` For the remainder of this vignette, we continue with the logistic regression model for explainability and reporting, as it offers the most directly interpretable coefficients for clinical use. ## 5. Explain the model ```{r} tr_explain(pima_model, method = "permutation") ``` Glucose consistently emerges as the strongest predictor of diabetes in this dataset, consistent with established clinical literature. ## 6. Automated pipeline review `tr_agent_review()` checks for common clinical modelling pitfalls: class imbalance, low events-per-variable ratio, possible data leakage, and small sample size. ```{r} pima_review <- tr_agent_review(pima_train, pima_model, use_agent = FALSE) ``` ## 7. Sensitivity analysis ```{r} pima_sensitivity <- tr_sensitivity(pima_train, pima_model) ``` ## 8. Generate a TRIPOD+AI-aligned report Finally, all of the above can be compiled into a single reproducible report, aligned with TRIPOD+AI reporting guidance. ```{r, eval = FALSE} tr_tripod_report( model = pima_model, validation = pima_validation, review = pima_review, sensitivity = pima_sensitivity, output_file = file.path(tempdir(), "pima_diabetes_report"), format = "html" ) ``` ## Optional: AI-assisted method recommendation If a Gemini API key is configured (see `?tr_recommend_method`), triageR can also suggest an appropriate statistical or ML approach based on the structure of your data: ```{r, eval = FALSE} tr_recommend_method( pima_train, outcome = "diabetes", context = "predicting diabetes onset in adult women" ) ``` ## Summary This vignette covered the full triageR workflow: loading and cleaning clinical data, handling missingness, fitting and validating a model, explainability, automated pipeline review, sensitivity analysis, and reproducible reporting, all using a real clinical dataset.