Computational Provenance & Reproducibility Record

RAISINS - R and AI Solutions for INferential Statistics · Online Statistical Analysis Platform for Agricultural Research

Computational Provenance & Reproducibility Record Discriminant Function Analysis · 1.0.0 · DOI 10.5281/zenodo.21935423

Computational Provenance & Reproducibility Record

RAISINS · Discriminant Function Analysis Module

This Computational Provenance Record documents the statistical computing environment, software dependencies, computational provenance, and bibliographic references associated with the RAISINS Discriminant Function Analysis module. It is intended to support computational reproducibility and software transparency. Detailed statistical methodology, mathematical derivations, and user guidance are provided separately in the official module documentation.

Any issues or updates required please comment here

Go to the App from here

1 Module Metadata

Parameter Specification
Module Discriminant Function Analysis
Module Version 1.0.0
DOI 10.5281/zenodo.21935423
Document Type Computational workflow
Statistical Engine R
R Version 4.5.2
Reproducibility Execution Environment: Posit Connect · GCR · renv-locked

2 Statistical Dependency Manifest

Package Version Repository Core Statistical Functions
MASS 7.3-65 CRAN lda(), qda()
heplots 1.8.1 CRAN boxM()
caret 7.0-1 CRAN createDataPartition(), confusionMatrix()
stats 4.5.2 Base R predict(), as.formula(), na.omit()

3 Statistical Function Registry

Analytical Role Primary Function(s)
Homogeneity of covariance matrices heplots::boxM()
Train/test partitioning caret::createDataPartition()
Classification model (linear) MASS::lda()
Classification model (quadratic) MASS::qda()
Class prediction (test split and new data) stats::predict() (predict.lda() / predict.qda())
Model performance evaluation caret::confusionMatrix()

4 Default Methods & Parameters

Analysis Step / Parameter Default Method / Value
Response &
Predictor
Validation
Response variable Must be qualitative (factor, character, or logical) with at least two classes; predictor variables must all be numeric. Rows with any missing value across the selected variables are dropped via na.omit() before fitting
Probability input Training-split proportion must be a number strictly between 0 and 1 (validated before fitting)
Homogeneity of
Covariance

(boxM())
Test Box's M test for equality of covariance matrices across the grouping variable's classes, computed on the selected predictors
Interpretation (informational only) p > 0.05 ⇒ homogeneity holds, Linear Discriminant Analysis (LDA) is considered appropriate; p ≤ 0.05 ⇒ covariance matrices differ significantly, Quadratic Discriminant Analysis (QDA) may be more appropriate. This is advisory text shown to the user — the app does not automatically switch models based on the test result
Train/Test
Split

(createDataPartition())
Training proportion p = 0.8 (80% train / 20% test), user-adjustable via the Probability control, range (0, 1) exclusive
Reproducibility set.seed(123) is fixed immediately before partitioning, so the same train/test split is produced on every run for a given dataset and probability
Classification
Model

(lda() /
qda())
Default model Linear Discriminant Analysis (MASS::lda()); Quadratic Discriminant Analysis (MASS::qda()) selectable instead. Formula is grouping variable ~ selected predictors
Prior probabilities Not user-specified; both lda() and qda() default to the observed class proportions in the training split (empirical priors)
QDA fitting failure If a training class does not contain enough observations to estimate a separate covariance matrix, qda()'s error is caught with tryCatch(); the user is shown a dialog suggesting a larger training proportion, fewer predictors, or LDA instead, and no model is produced
Model
Evaluation

(confusionMatrix())
Evaluation set The held-out test split (never the training data); predictions from predict(model, newdata = test)$class are compared against the true test-set classes
Per-class metrics (branch) When cm$byClass is returned as a matrix (three or more classes), it is used directly. When the grouping variable has exactly two classes, caret::confusionMatrix() returns byClass as a single vector, so the app instead loops over each class level and recomputes confusionMatrix(..., positive = class) to obtain one-vs-rest sensitivity/specificity for every class
New-Data
Prediction
Variable matching Predictions on a separately uploaded dataset use the full multi-predictor model (predict(model, newdata = new_data)); if any predictor used to fit the model is absent from the new dataset, a dialog lists the missing variable(s) and prediction is withheld

5 R Code for Key Analytical Steps

The code blocks below demonstrate the exact computation behind each reported result using the built-in iris dataset (Species as the grouping variable; Sepal.Length, Sepal.Width, Petal.Length, Petal.Width as numeric predictors) from the datasets package.

5.1 Validation, Homogeneity Test, and Train/Test Split

data(iris)
response   <- "Species"
predictors <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")

dfa_df <- iris[, c(response, predictors)]
dfa_df[[response]] <- as.factor(dfa_df[[response]])   # response must be qualitative
dfa_df <- na.omit(dfa_df)                              # drop incomplete rows

# Box's M test - homogeneity of covariance matrices across groups
library(heplots)
boxm_result <- boxM(Y = dfa_df[, predictors], group = dfa_df[[response]])
boxm_result$statistic; boxm_result$parameter; boxm_result$p.value
# p >  0.05 -> homogeneity holds, LDA appropriate (RAISINS default)
# p <= 0.05 -> covariance matrices differ, QDA may be preferable (advisory only)

set.seed(123)                                          # fixed by RAISINS for reproducibility
library(caret)
train_index <- createDataPartition(dfa_df[[response]], p = 0.8, list = FALSE)  # 80% default split
train <- dfa_df[train_index, ]
test  <- dfa_df[-train_index, ]

5.2 Fitting LDA/QDA and Evaluating on the Test Split

library(MASS)
form <- as.formula(paste(response, "~", paste(predictors, collapse = " + ")))

# Default model = LDA; prior probabilities default to training-class proportions
lda_model <- lda(form, data = train)
lda_model$prior                                # empirical class priors
lda_model$means                                 # per-class predictor means
prop_trace <- (lda_model$svd^2) / sum(lda_model$svd^2)
prop_trace                                      # proportion of between-group variance per LD

pred <- predict(lda_model, newdata = test)      # class predictions on the held-out test split

library(caret)
cm <- confusionMatrix(data = pred$class, reference = test[[response]])
cm$table                                        # confusion matrix
cm$overall                                      # Accuracy, Kappa, etc.
cm$byClass                                      # per-class sensitivity/specificity (matrix for >= 3 classes)

# QDA alternative (selectable); can fail if a class has too few training observations
qda_model <- qda(form, data = train)

Explore the entire Discriminant Function Analysis module in preview mode using our demo datasets. To submit suggestions or report a workflow issue, please use the discussion section below, or visit the official RAISINS website.

6 RAISINS Native Statistical Framework

RAISINS uses R for all its statistical computations. Every package used to generate major results is listed and demonstrated with examples, so results can be reproduced independently. These results are then organized and formatted on the RAISINS website along with visualisation to make them easier to use and interpret. RAISINS also has its own custom-built statistical tools for managing workflows, validating results, and generating reports. Details of these are not fully covered here, they’re shared with outside researchers only on request, and are subject to licensing terms.

7 Package References

R Core Team. (2025). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. https://www.R-project.org/

Ripley, B., Venables, B., Bates, D. M., Hornik, K., Gebhardt, A., & Firth, D. (2025). MASS: Support Functions and Datasets for Venables and Ripley’s MASS (R package version 7.3-65). https://doi.org/10.32614/CRAN.package.mass

Fox, J., Friendly, M., & Monette, G. (2024). heplots: Visualizing Hypothesis Tests in Multivariate Linear Models (R package version 1.8.1). https://doi.org/10.32614/CRAN.package.heplots

Kuhn, M. (2025). caret: Classification and Regression Training (R package version 7.0-1). https://doi.org/10.32614/CRAN.package.caret

Allaire, J. J., Xie, Y., Dervieux, C., McPherson, J., Luraschi, J., Ushey, K., Atkins, A., Wickham, H., Cheng, J., Chang, W., & Iannone, R. (2026). rmarkdown: Dynamic Documents for R (R package version 2.30). https://github.com/rstudio/rmarkdown

Feedback & Discussion