SyntaxStudy
Sign Up
R ANOVA, Logistic Regression, and Model Evaluation
R Beginner 2 min read

ANOVA, Logistic Regression, and Model Evaluation

Analysis of Variance (ANOVA) tests whether the means of three or more groups are significantly different. In R, aov() fits an ANOVA model using the same formula interface as lm(). The summary() of an aov object prints the ANOVA table with sums of squares, mean squares, F-statistics, and p-values. For post-hoc pairwise comparisons following a significant ANOVA, TukeyHSD() computes simultaneous confidence intervals for all pairs of group means with family-wise error control. Logistic regression models a binary outcome as a function of predictors using the generalised linear model framework. The glm() function with family = binomial fits a logistic regression, estimating log-odds coefficients. Exponentiating the coefficients with exp(coef()) converts them to odds ratios, which are more interpretable. The predict() function with type = "response" returns fitted probabilities rather than log-odds. Model performance for classification is evaluated with a confusion matrix (from the caret or yardstick packages) and metrics like accuracy, sensitivity, specificity, and AUC. Cross-validation is the standard approach for unbiased model evaluation. The caret package provides a unified interface for training and cross-validating dozens of models, and the tidymodels framework (rsample, parsnip, recipes, tune) offers a modern tidyverse-style workflow for the same purpose. For simple k-fold cross-validation of a linear model, the cv.lm() function from the DAAG package or a manual split with rsample::vfold_cv() are straightforward starting points.
Example
# One-way ANOVA
data(PlantGrowth)   # weight of plants under 3 conditions

aov_model <- aov(weight ~ group, data = PlantGrowth)
summary(aov_model)

# Post-hoc: Tukey HSD
TukeyHSD(aov_model)

# Two-way ANOVA
data(ToothGrowth)
aov2 <- aov(len ~ supp * dose, data = ToothGrowth)
summary(aov2)

# Logistic regression
# Create a binary outcome
data(mtcars)
mtcars$am <- factor(mtcars$am, labels = c("automatic", "manual"))

log_model <- glm(am ~ mpg + wt + hp,
                 data   = mtcars,
                 family = binomial)
summary(log_model)

# Coefficients as odds ratios
exp(coef(log_model))
exp(confint(log_model))

# Fitted probabilities
fitted_probs <- predict(log_model, type = "response")
predicted_class <- ifelse(fitted_probs > 0.5, "manual", "automatic")

# Confusion matrix (manual)
table(Predicted = predicted_class, Actual = mtcars$am)

# Accuracy
mean(predicted_class == as.character(mtcars$am))

# Likelihood ratio test (compare to null model)
null_model <- glm(am ~ 1, data = mtcars, family = binomial)
anova(null_model, log_model, test = "LRT")

# Pseudo R-squared (McFadden)
1 - log_model$deviance / null_model$deviance