| Type: | Package |
| Title: | Staggered Regression Discontinuity with Network Interference |
| Version: | 0.1.0 |
| Description: | Implements a unified framework combining staggered difference-in-differences with regression discontinuity designs and network interference. Extends Callaway and Sant'Anna (2021) <doi:10.1016/j.jeconom.2020.12.001> to settings where treatment assignment is determined by a running variable crossing a cutoff, adoption timing is heterogeneous across units, and spillover effects operate through a known network structure. Provides group-time average treatment effects (direct and spillover), aggregation schemes, bandwidth selection, and pre-treatment falsification tests. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.3 |
| Depends: | R (≥ 4.0.0) |
| Imports: | stats, sandwich, ggplot2, rdrobust, |
| Suggests: | testthat (≥ 3.0.0), knitr, rmarkdown, dplyr, covr |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| URL: | https://github.com/causalfragility-lab/rdstagger |
| BugReports: | https://github.com/causalfragility-lab/rdstagger/issues |
| NeedsCompilation: | no |
| Packaged: | 2026-05-02 22:28:37 UTC; Subir |
| Author: | Subir Hait [aut, cre] |
| Maintainer: | Subir Hait <haitsubi@msu.edu> |
| Repository: | CRAN |
| Date/Publication: | 2026-05-05 18:50:02 UTC |
rdstagger: Staggered Regression Discontinuity with Network Interference
Description
Implements a unified framework combining staggered difference-in-differences with regression discontinuity designs and network interference. Extends Callaway and Sant'Anna (2021) to settings where:
Treatment assignment is determined by a running variable crossing a cutoff (RD)
Treatment adoption timing is heterogeneous across units (staggered DiD)
Spillover effects operate through a known network structure (interference)
Main functions
sim_rdstaggerSimulate a staggered RD panel dataset with interference
rdstagger_bwOptimal bandwidth selection per cohort-time cell
rdstagger_attgtEstimate ATT(g,t) — direct and spillover effects
rdstagger_spilloverEstimate spillover effects at network distance d
rdstagger_aggAggregate ATT(g,t) into event-study or overall ATT
rdstagger_pretestPre-treatment parallel trends falsification tests
References
Callaway, B., & Sant'Anna, P. H. C. (2021). Difference-in-differences with multiple time periods. Journal of Econometrics, 225(2), 200-230.
Calonico, S., Cattaneo, M. D., & Titiunik, R. (2014). Robust nonparametric confidence intervals for regression-discontinuity designs. Econometrica, 82(6), 2295-2326.
Manski, C. F. (2013). Identification of treatment response with social interactions. The Econometrics Journal, 16(1), S1-S23.
Author(s)
Maintainer: Subir Hait haitsubi@msu.edu
See Also
Useful links:
Report bugs at https://github.com/causalfragility-lab/rdstagger/issues
Plot Aggregated ATT Estimates
Description
Produces a ggplot2 event-study or aggregation plot from an
"rdstagger_agg" object.
Usage
## S3 method for class 'rdstagger_agg'
plot(x, ...)
Arguments
x |
An object of class |
... |
Additional arguments (currently unused). |
Value
A ggplot2 object.
Examples
sim <- sim_rdstagger(n = 300, nperiods = 6, n_cohorts = 2,
true_direct = 0.3, seed = 42)
res <- rdstagger_attgt(data = sim$data, yname = "y", xname = "x",
gname = "g", tname = "period", idname = "id",
bw = 1.5, boot = FALSE)
agg <- rdstagger_agg(res, type = "dynamic")
plot(agg)
Aggregate ATT(g,t) Estimates
Description
Aggregates group-time average treatment effects ATT(g,t) from
rdstagger_attgt into summary estimands: event-study
(dynamic), cohort-level, calendar-time, or overall ATT.
Usage
rdstagger_agg(
x,
type = c("dynamic", "group", "calendar", "overall"),
min_periods = 1L
)
Arguments
x |
An object of class |
type |
Character. Aggregation type: |
min_periods |
Integer. Minimum number of cohort-time cells required
to include an event-time bin. Default |
Value
An object of class "rdstagger_agg", a list with:
aggData frame of aggregated estimates
typeAggregation type used
overall_attSimple overall ATT (post-treatment average)
attgtThe original ATT(g,t) data frame
Examples
sim <- sim_rdstagger(n = 300, nperiods = 6, n_cohorts = 2,
true_direct = 0.3, seed = 42)
res <- rdstagger_attgt(data = sim$data, yname = "y", xname = "x",
gname = "g", tname = "period", idname = "id",
bw = 1.5, boot = FALSE)
# Event study
agg_dyn <- rdstagger_agg(res, type = "dynamic")
print(agg_dyn)
plot(agg_dyn)
# Overall ATT
agg_ov <- rdstagger_agg(res, type = "overall")
print(agg_ov)
Estimate Group-Time Average Treatment Effects in Staggered RD
Description
Main estimation function for the staggered RD framework with network
interference. Estimates ATT(g, t) — the average treatment effect for
cohort g at time t — separately for direct effects on
treated units and spillover effects on their network neighbors, within
an RD bandwidth around the cutoff.
Usage
rdstagger_attgt(
data,
yname,
xname,
cutoff = 0,
gname,
tname,
idname,
network = NULL,
bw = "optimal",
control_group = c("nevertreated", "notyetreated"),
xformla = NULL,
doubly_robust = TRUE,
boot = TRUE,
nboot = 999L,
alpha = 0.05,
kernel = c("triangular", "epanechnikov", "uniform")
)
Arguments
data |
A |
yname |
Character. Outcome variable name. |
xname |
Character. Running variable name. |
cutoff |
Numeric. RD cutoff. Default |
gname |
Character. Cohort variable name ( |
tname |
Character. Time period variable name. |
idname |
Character. Unit identifier variable name. |
network |
Matrix or |
bw |
Numeric or |
control_group |
Character. Which units form the control group.
|
xformla |
Formula or |
doubly_robust |
Logical. Use doubly-robust estimator. Default |
boot |
Logical. Compute bootstrap standard errors. Default |
nboot |
Integer. Number of bootstrap replications. Default |
alpha |
Numeric. Significance level for confidence intervals.
Default |
kernel |
Character. RD kernel. Default |
Value
An object of class "rdstagger_attgt", a list with:
attgtData frame of ATT(g,t) estimates (direct effects)
spillgtData frame of spillover ATT(g,t) estimates (if
networksupplied)argsList of call arguments
bandwidthBandwidth used
Examples
sim <- sim_rdstagger(n = 300, nperiods = 6, n_cohorts = 2,
true_direct = 0.3, true_spill = 0.1, seed = 42)
res <- rdstagger_attgt(
data = sim$data,
yname = "y",
xname = "x",
cutoff = 0,
gname = "g",
tname = "period",
idname = "id",
network = sim$network,
bw = 1.5,
boot = FALSE
)
print(res)
Bandwidth Selection for Staggered RD
Description
Computes an optimal bandwidth for each cohort-time cell using the
mean-squared-error-optimal bandwidth selector from rdrobust.
Separate bandwidths are estimated for pre-treatment and post-treatment
periods to ensure appropriate comparison groups.
Usage
rdstagger_bw(
data,
yname,
xname,
cutoff = 0,
gname,
tname,
kernel = c("triangular", "epanechnikov", "uniform"),
bw_common = FALSE
)
Arguments
data |
A |
yname |
Character. Name of the outcome variable column. |
xname |
Character. Name of the running variable column. |
cutoff |
Numeric. The RD cutoff value. Default 0. |
gname |
Character. Name of the cohort variable column
( |
tname |
Character. Name of the time period column. |
kernel |
Character. Kernel for RD estimation. One of
|
bw_common |
Logical. If |
Value
A list with elements:
bw_matrixA matrix of bandwidths with rows = cohorts, columns = time periods
bw_commonSingle common bandwidth (median across cells)
bw_summaryA
data.framesummarising bandwidths by cohort and period
Examples
sim <- sim_rdstagger(n = 400, nperiods = 6, n_cohorts = 2, seed = 42)
bw <- rdstagger_bw(data = sim$data, yname = "y", xname = "x",
cutoff = 0, gname = "g", tname = "period")
bw$bw_common
bw$bw_summary
Pre-Treatment Falsification Tests for Staggered RD
Description
Tests the pre-treatment parallel trends assumption within the RD
bandwidth. Performs a joint test across all pre-treatment cohort-time
cells and individual cell tests, analogous to pretest in the
did package but adapted for the staggered RD setting.
Usage
rdstagger_pretest(x, method = c("joint", "individual", "both"))
Arguments
x |
An object of class |
method |
Character. Test method: |
Value
A list with elements:
jointJoint test statistic, df, and p-value (if requested)
individualData frame of per-cell tests (if requested)
passesLogical.
TRUEif joint test p-value > 0.05
Examples
sim <- sim_rdstagger(n = 400, nperiods = 8, n_cohorts = 2,
true_direct = 0.3, seed = 42)
res <- rdstagger_attgt(data = sim$data, yname = "y", xname = "x",
gname = "g", tname = "period", idname = "id",
bw = 1.5, boot = FALSE)
pt <- rdstagger_pretest(res)
print(pt)
Estimate Spillover Effects in Staggered RD
Description
Estimates the spillover (indirect) treatment effects on network neighbors of treated units within the RD bandwidth. Spillover effects are estimated separately for each cohort-time cell.
Usage
rdstagger_spillover(
data,
yname,
xname,
cutoff = 0,
gname,
tname,
idname,
network,
bw,
kernel = c("triangular", "epanechnikov", "uniform"),
boot = TRUE,
nboot = 999L,
alpha = 0.05
)
Arguments
data |
A |
yname |
Character. Outcome variable name. |
xname |
Character. Running variable name. |
cutoff |
Numeric. RD cutoff. Default |
gname |
Character. Cohort variable name. |
tname |
Character. Time period variable name. |
idname |
Character. Unit identifier variable name. |
network |
Matrix. |
bw |
Numeric. Bandwidth around the cutoff. |
kernel |
Character. RD kernel. Default |
boot |
Logical. Bootstrap standard errors. Default |
nboot |
Integer. Bootstrap replications. Default |
alpha |
Numeric. Significance level. Default |
Value
A data.frame with columns:
cohortTreatment cohort
periodTime period
spill_attSpillover ATT estimate
seStandard error
ci_lower,ci_upperConfidence interval
pvalp-value
n_exposedNumber of exposed neighbors
Examples
sim <- sim_rdstagger(n = 300, nperiods = 6, n_cohorts = 2,
true_direct = 0.3, true_spill = 0.15, seed = 42)
sp <- rdstagger_spillover(
data = sim$data, yname = "y", xname = "x",
gname = "g", tname = "period", idname = "id",
network = sim$network, bw = 1.5, boot = FALSE
)
head(sp)
Simulate a Staggered RD Panel Dataset with Network Interference
Description
Generates synthetic panel data suitable for testing and demonstrating
the rdstagger estimators. The data generating process features
a running variable with a cutoff-based treatment assignment, staggered
adoption across cohorts, and network spillover effects.
Usage
sim_rdstagger(
n = 500,
nperiods = 8,
n_cohorts = 3,
cutoff = 0,
bw = 1,
network_density = 0.1,
true_direct = 0.3,
true_spill = 0.1,
outcome_type = c("continuous", "binary", "count"),
heterogeneous_te = FALSE,
seed = NULL
)
Arguments
n |
Integer. Number of units. Default 500. |
nperiods |
Integer. Number of time periods. Default 8. |
n_cohorts |
Integer. Number of treatment cohorts. Default 3. |
cutoff |
Numeric. RD cutoff value on the running variable. Default 0. |
bw |
Numeric. True bandwidth around the cutoff. Default 1. |
network_density |
Numeric. Probability of a network tie between any two units (Erdos-Renyi model). Must be in (0, 1). Default 0.1. |
true_direct |
Numeric. True direct average treatment effect. Default 0.3. |
true_spill |
Numeric. True spillover effect on network neighbors. Default 0.1. |
outcome_type |
Character. One of |
heterogeneous_te |
Logical. If |
seed |
Integer. Random seed for reproducibility. Default |
Value
A list with three elements:
dataA
data.framewith columns:id,period,y,x(running variable),g(cohort,Inffor never-treated),treated,neighbor_treated,spillover_sharenetworkAn
n \times nadjacency matrixtrue_paramsA list of the true parameter values used to generate the data
Examples
# Basic continuous outcome
sim <- sim_rdstagger(n = 300, nperiods = 6, n_cohorts = 2,
true_direct = 0.3, true_spill = 0.1, seed = 42)
head(sim$data)
sim$true_params
# Binary outcome
sim_bin <- sim_rdstagger(n = 500, nperiods = 8, n_cohorts = 3,
outcome_type = "binary", seed = 123)
table(sim_bin$data$y)
# Count outcome
sim_cnt <- sim_rdstagger(n = 400, nperiods = 6, n_cohorts = 2,
outcome_type = "count", true_direct = 0.5,
seed = 999)