Extracts the fully disaggregated treatment-effect estimates from a fitted
FETWFE / ETWFE / BETWFE object: one row for every (cohort, time) cell, with
no averaging over cohorts or over event time. This is the finest-grained view
of the estimated effects — the num_treats underlying parameters
themselves — complementing cohortStudy() (which averages each cohort's
cells over time) and eventStudy() (which averages over cohorts at each
event time).
Like eventStudy(), this accessor is not available for twfeCovs() objects:
that estimator has a single treatment-effect parameter per cohort (no
per-time disaggregation), so its finest granularity is already
cohortStudy().
Standard errors are the per-cell regression standard errors
\(\sqrt{\sigma_\varepsilon^2 \, \psi' G^{-1} \psi / (NT)}\), recomputed at
call time from the fit's stored design (the same Gram-matrix machinery
eventStudy() uses; nothing is added to the fitted object). Because each
cell is a single cohort-time parameter, the cohort-probability sampling
variance that contributes to the aggregated cohortStudy() /
eventStudy() standard errors is identically zero here, so a cell's SE is a
single coefficient's regression SE.
Confidence intervals and p-values are pointwise \(1 - \alpha\) Wald
quantities (estimate +/- z * se). For simultaneous (family-wise) bands
over the cell family, use
simultaneousCIs(result, family = "all_post_treatment").
Arguments
- result
A fitted object from
fetwfe(),etwfe(), orbetwfe()(or their*WithSimulatedData()wrapper analogs, which return the same classes).twfeCovs()objects are not supported (see Description).- alpha
Numeric in
(0, 1); the pointwise confidence level is1 - alpha. Defaults to thealphastored on the fit.
Value
A data frame with class c("cohortTimeATTs", "data.frame")
containing one row per (cohort, time) treatment-effect cell, sorted by
cohort then time, with columns:
- cohort
Character; the cohort label (the calendar time at which the cohort first received treatment), matching
cohortStudy().- time
Numeric; the calendar time of the cell, equal to the cohort's adoption time plus the event time (
0, 1, ...). Real panels carry their actual calendar times. For syntheticgenCoefs()/simulateData()fixtures (whose panel runs1, ..., T, so the stored first year is1) this coincides with the 1-based panel-time index. (Only a hand-built or legacy fit with no stored first year falls back to that panel-time index directly.)- estimate
Numeric; the cell's ATT estimate.
- se
Numeric; the pointwise standard error.
0for a cell zeroed out by the fusion/bridge penalty while other cells survive (fetwfe()/betwfe());NAwhen standard errors are unavailable — the fit was computed withq >= 1, the Gram matrix on the selected support is singular, or the penalty zeroed the entire treatment block (no cells selected, so there is no support to recompute the Gram from; this matcheseventStudy()).- ci_low, ci_high
Numeric; the pointwise
1 - alphaWald boundsestimate -/+ qnorm(1 - alpha/2) * se.(0, 0)for a fused-away cell;NAwhenseisNA.- p_value
Numeric; the two-sided pointwise Wald p-value
2 * pnorm(-|estimate / se|).NAwhenseis0orNA.- selected
(
fetwfe()/betwfe()only.) Logical;TRUEwhen the bridge penalty left the cell's estimate nonzero. Absent foretwfe(), which does not perform selection.
Use tidy(cohortTimeATTs(result)) (with the broom package loaded) to
reshape to broom convention; see tidy.cohortTimeATTs().
Details
The cell standard error is computed from psi, the cell's row of the
(selected) treatment-effect design — for fetwfe() the relevant row of the
inverse fusion transform \(D^{-1}\) in the transformed (theta) coordinate
space, for betwfe() / etwfe() a unit selector in the original (beta)
coordinate space restricted to the selected support. It is
never gated on the point estimate: a cell whose estimate is exactly zero
because the penalty fused it away has an all-zero psi and therefore
se = 0 (the correct degenerate value), while a cell whose estimate happens
to be near zero for other reasons still receives its proper nonzero SE.
See also
cohortStudy() for the per-cohort (time-averaged) accessor;
eventStudy() for the per-event-time (cohort-averaged) accessor;
simultaneousCIs() for simultaneous (family-wise) bands over the cell
family (family = "all_post_treatment"); tidy.cohortTimeATTs() for
broom-shape translation.
Examples
if (FALSE) { # \dontrun{
coefs <- genCoefs(G = 3, T = 6, d = 2, density = 0.5, eff_size = 2)
dat <- simulateData(coefs, N = 120, sig_eps_sq = 1, sig_eps_c_sq = 0.5, seed = 123)
res <- fetwfeWithSimulatedData(dat)
cta <- cohortTimeATTs(res)
cta
# Broom-shape translation:
if (requireNamespace("broom", quietly = TRUE)) {
broom::tidy(cta)
}
} # }