You already know what an analysis of variance (ANOVA) is and when it is used. Now let’s get practical: You’ll get a complete workflow for a one-way ANOVA in R – including assumption tests, the model, post-hoc tests, and plots.
The example: Learning methods and exam performance
Imagine you want to find out whether different learning methods affect students’ test scores. You have three groups:
- Flashcards
- Videos
- Group work
Here is the fictional data:
# Create example data
lerndaten <- data.frame(
methode = factor(rep(c("Flashcards", "Videos", "Group work"), each = 10)),
punkte = c(78, 85, 80, 82, 75, 79, 84, 81, 77, 76, # Flashcards
72, 70, 68, 74, 69, 71, 67, 73, 70, 69, # Videos
90, 88, 87, 85, 91, 89, 92, 90, 86, 88) # Group work
)
1. Explore the data
An initial overview helps you understand the data:
summary(lerndaten)
boxplot(punkte ~ methode, data = lerndaten,
col = "lightblue", main = "Scores by learning method",
ylab = "Score", xlab = "Method")
This gives you an initial idea of whether differences are visible.
2. Testing the assumptions
Before we get started: ANOVA requires certain assumptions. Let’s check them step by step.
Definition (Box):
Assumptions for the one-way ANOVA:
- Normality of the residuals
- Homogeneity of variances
- Independence of observations
a) Checking normality
# Extract residuals
modell <- aov(punkte ~ methode, data = lerndaten)
residuen <- residuals(modell)
# QQ plot
qqnorm(residuen)
qqline(residuen, col = "red")
# Shapiro-Wilk test
shapiro.test(residuen)
Interpretation:
- Points on the QQ line → good
- $p > 0{,}05$ in the Shapiro test → normality is acceptable
b) Checking homogeneity of variances
install.packages("car") # only the first time
library(car)
leveneTest(punkte ~ methode, data = lerndaten)
Interpretation:
- $p > 0{,}05$ → equal variances
- $p < 0{,}05$ → it is better to use Welch’s ANOVA
c) Checking independence
This assumption must be checked substantively.
Important: Each person may be assigned to only one group and may be measured only once.
3. Conducting a one-way ANOVA
# Run ANOVA
modell <- aov(punkte ~ methode, data = lerndaten)
summary(modell)
Example output:
Df Sum Sq Mean Sq F value Pr(>F)
methode 2 1022.1 511.1 24.52 1.2e-06 ***
Residuals 27 562.2 20.8
Definition (Box):
F-value: Ratio of explained to unexplained variance.
p-value: Probability that an F-value this large arises by chance.
Result:
The differences are statistically significant ($p < 0{,}001$).
4. Post-hoc test: Which groups differ?
TukeyHSD(model)
Example output:
cssCopyEdit diff lwr upr p adj
Videos-Flashcards -9.40 -13.97 -4.83 0.0002
Group work-Flashcards 9.80 5.23 14.37 0.0001
Group work-Videos 19.20 13.63 24.77 0.0000
Interpretation:
All groups differ significantly from one another.
5. Bonus: Visualization with ggplot2
library(ggplot2)
ggplot(lerndaten, aes(x = methode, y = punkte)) +
geom_boxplot(fill = "lightgreen") +
theme_minimal() +
labs(title = "Exam performance by learning method",
x = "Learning method", y = "Points")
Summary: One-Way ANOVA in 5 Steps
| Step | What happens? |
|---|---|
| 1. | Prepare and inspect the data |
| 2. | Test the assumptions (normality, homogeneity of variance, independence) |
| 3. | Use aov() |
| 4. | Interpret the results |
| 5. | Use TukeyHSD() for post-hoc comparisons |
Q&A – Test Your Knowledge
Question 1: Why do you check the assumptions before conducting an ANOVA?
Answer: Because otherwise, the test results may be biased or invalid.
Question 2: What does a significant F-value mean?
Answer: It means that at least one group differs significantly from the others.
Question 3: When do you need a post-hoc test?
Answer: When the ANOVA is significant and you want to know which groups differ.
Question 4: How do you test the normality of the residuals in R?
Answer: With shapiro.test(residuals) or a QQ plot.
Question 5: How do you check for homogeneity of variance?
Answer: With leveneTest() from the car package.
Alles klar?
Ich hoffe, der Beitrag war für dich soweit verständlich. Wenn du weitere Fragen hast, nutze bitte hier die Möglichkeit, eine Frage an mich zu stellen!
