DataFrame Panels
MSC.jl includes a small long-panel helper for common-adoption designs. Treatment must be binary, controls must never be treated, and treated units must remain treated after the first post-treatment period.
using MSC
using DataFrames
sim = simulate_msc(ncontrols = 12, ntreated = 3, T0 = 40, T1 = 5, tau = 2.0, seed = 4)
rows = NamedTuple[]
for i in eachindex(sim.units), t in eachindex(sim.times)
push!(
rows,
(
unit = sim.units[i],
time = sim.times[t],
outcome = sim.Y[i, t],
treated = sim.W[i, t],
),
)
end
df = DataFrame(rows)
first(df, 5)5×4 DataFrame
| Row | unit | time | outcome | treated |
|---|---|---|---|---|
| String | Int64 | Float64 | Float64 | |
| 1 | control_1 | 1 | 0.76673 | 0.0 |
| 2 | control_1 | 2 | 3.51415 | 0.0 |
| 3 | control_1 | 3 | -2.87369 | 0.0 |
| 4 | control_1 | 4 | 2.71514 | 0.0 |
| 5 | control_1 | 5 | -2.18076 | 0.0 |
Convert the long table to matrix form:
panel = panel_matrices(df, :unit, :time, :outcome, :treated)
(size(panel.Y), panel.N0, panel.T0)((15, 45), 12, 40)Estimate directly from the table:
est = msc_estimate(
df,
:unit,
:time,
:outcome,
:treated;
lambdas = [0.002],
max_iter = 1000,
tol = 1e-6,
)
round(est.estimate, digits = 3)2.031The table labels are preserved for diagnostics:
first(weights_table(est; atol = 1e-8), 10)10×3 DataFrame
| Row | control | treated | weight |
|---|---|---|---|
| Any | Any | Float64 | |
| 1 | control_1 | treated_1 | 0.0422069 |
| 2 | control_12 | treated_1 | -0.0635816 |
| 3 | control_3 | treated_1 | 0.34683 |
| 4 | control_4 | treated_1 | 0.0660343 |
| 5 | control_5 | treated_1 | 0.0501473 |
| 6 | control_6 | treated_1 | -0.114599 |
| 7 | control_7 | treated_1 | -0.0236845 |
| 8 | control_8 | treated_1 | -0.151047 |
| 9 | control_9 | treated_1 | 0.30177 |
| 10 | control_1 | treated_2 | 0.154887 |