Implements a hierarchical penalized spline framework for estimating
achievement gap trajectories in longitudinal educational data.
The achievement gap between two groups (e.g., low versus high
socioeconomic status) is modeled directly as a smooth function
of grade while the baseline trajectory is estimated simultaneously
within a mixed-effects model. Smoothing parameters are selected
using restricted maximum likelihood (REML), and simultaneous
confidence bands with correct joint coverage are constructed
using posterior simulation. The package also includes functions
for simulation-based benchmarking, visualization of gap
trajectories, and hypothesis testing for global and
grade-specific differences. The modeling framework builds on
penalized spline methods (Eilers and Marx, 1996,

achieveGap provides a joint hierarchical penalized spline framework for estimating achievement gap trajectories in longitudinal educational data.
Most existing approaches model group-specific trajectories separately and derive the gap as a post hoc difference — ignoring covariance between estimates and producing incorrect uncertainty quantification. achieveGap parameterizes the gap directly as a smooth function of grade, estimated simultaneously with the baseline trajectory within a mixed-effects model. Simultaneous confidence bands with correct joint coverage are constructed via posterior simulation.
# CRAN (once published)
install.packages("achieveGap")
# Development version from GitHub
# install.packages("devtools")
devtools::install_github("causalfragility-lab/achieveGap")
library(achieveGap)
# 1. Simulate data
sim <- simulate_gap(n_students = 400, n_schools = 30,
gap_shape = "monotone", seed = 2024)
# 2. Fit the model
fit <- gap_trajectory(
data = sim$data,
score = "score",
grade = "grade",
group = "SES_group",
school = "school",
student = "student"
)
# 3. Summarize and visualize
summary(fit)
plot(fit, grade_labels = c("K","G1","G2","G3","G4","G5","G6","G7"))
# 4. Test the gap
test_gap(fit, type = "both")
The model takes the form:
$$Y_{ijt} = \beta_0 + f_0(t) + G_{ij} f_1(t) + Z_{ijt}^\top \delta + u_j + v_i + \epsilon_{ijt}$$
where:
Both smooth functions are penalized cubic regression splines estimated via
mgcv::gamm() with REML.
| Function | Description |
|---|---|
gap_trajectory() |
Fit the joint hierarchical spline model |
plot() |
Gap trajectory with simultaneous/pointwise bands |
summary() |
Table of gap estimates and significance |
test_gap() |
Global and simultaneous hypothesis tests |
fit_separate() |
Comparison: separate splines per group |
simulate_gap() |
Generate synthetic longitudinal data |
run_simulation() |
Benchmark simulation study (reproduces paper tables) |
summarize_simulation() |
Print Tables 1 & 2 from simulation results |
This package accompanies:
Hait, S. (2024). Modeling Achievement Gap Trajectories Using Hierarchical Penalized Splines: A Mixed Effects Framework with an R Implementation. Journal of Educational and Behavioral Statistics.
GPL (>= 3)
The only change from your previous version is the Eilers & Marx DOI: `1177012843` → `1038425655`. You also need to make the same fix in `DESCRIPTION`:
(Eilers and Marx, 1996, doi:10.1214/ss/1038425655)