Define the Dataset

We start by creating a dataset to analyze. For this example, assume we have four groups with observed means.

data <- data.frame(
  Group = factor(rep(1:4, each = 5)), 
  Response = c(15, 16, 14, 15, 15, 20, 21, 19, 20, 22, 25, 26, 24, 25, 23, 30, 31, 29, 28, 30)
)

head(data)
##   Group Response
## 1     1       15
## 2     1       16
## 3     1       14
## 4     1       15
## 5     1       15
## 6     2       20

Fit the ANOVA Model

We start by fitting an ANOVA model to test the overall equality of means across the groups.

anova_model <- aov(Response ~ Group, data = data)

summary(anova_model)
##             Df Sum Sq Mean Sq F value   Pr(>F)    
## Group        3  577.2   192.4   174.9 1.94e-12 ***
## Residuals   16   17.6     1.1                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Define and Test Specific Contrasts

For example, compare the mean of group 1 with group 2.

contrast1 <- c(-1, 1, 0, 0)

contrast_matrix <- matrix(contrast1, ncol = 1)
contrasts(data$Group) <- contrast_matrix

anova_contrast <- aov(Response ~ Group, data = data)

summary(anova_contrast)
##             Df Sum Sq Mean Sq F value   Pr(>F)    
## Group        3  577.2   192.4   174.9 1.94e-12 ***
## Residuals   16   17.6     1.1                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Orthogonal Contrasts

Define orthogonal contrasts to test multiple hypotheses simultaneously.

contrast2 <- c(1, -1, 1, -1)  
contrast3 <- c(1, 1, -1, -1)  

contrast_matrix <- cbind(contrast2, contrast3)

contrasts(data$Group) <- contrast_matrix

anova_orthogonal <- aov(Response ~ Group, data = data)

summary(anova_orthogonal)
##             Df Sum Sq Mean Sq F value   Pr(>F)    
## Group        3  577.2   192.4   174.9 1.94e-12 ***
## Residuals   16   17.6     1.1                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Verify Orthogonality

Check if the contrasts are orthogonal.

contrast_matrix %*% t(contrast_matrix)
##      [,1] [,2] [,3] [,4]
## [1,]    2    0    0   -2
## [2,]    0    2   -2    0
## [3,]    0   -2    2    0
## [4,]   -2    0    0    2
If the off-diagonal elements are zero, the contrasts are orthogonal.

Visualize the Results

Visualize group means and confidence intervals to interpret contrasts.

library(ggplot2)

ggplot(data, aes(x = Group, y = Response)) +
  stat_summary(fun = mean, geom = "point", size = 4, color = "blue") +
  stat_summary(fun.data = mean_cl_normal, geom = "errorbar", width = 0.2) +
  labs(title = "Group Means and Confidence Intervals",
       x = "Group", y = "Response") +
  theme_minimal()