Did the tutoring program move the needle? A growth-analysis demonstration in R
R · tidyverse · mixed-effects models · reproducible analysis
This project demonstrates a reproducible approach to evaluating growth when groups begin at different levels and observations are clustered. It moves from a program-evaluation question to a mixed-effects model while keeping uncertainty and interpretation visible.
The analytical problem
Post-test averages alone cannot distinguish apparent program gains from differences in where groups began. A more useful analysis compares growth while accounting for repeated observations and group structure.
What the demonstration does
The workflow reshapes matched pre/post benchmark data, models change over time with mixed effects, and reports the estimated program-associated difference with an interval rather than relying only on a p-value.
Technical approach
library(tidyverse)
library(lme4)
library(broom.mixed)
long <- scores |>
pivot_longer(c(fall, spring),
names_to = "term",
values_to = "score")
m <- lmer(score ~ term * tutored +
(1 | class_id) +
(1 | student_id),
data = long)
tidy(m, conf.int = TRUE, effects = "fixed") |>
filter(str_detect(term, ":"))
Interpretation and limits
The analysis uses synthetic data so the full workflow can be inspected and rerun. It demonstrates matched pre/post structure, mixed-effects modeling, reproducible reporting, and the practice of stating limitations alongside results.
A production version would pair the code with a rendered Quarto report, a documented data dictionary, de-identified or synthetic rerunnable data, and a short stakeholder-facing summary.
Repository: View the reproducible R analysis on GitHub →