MethodAtlas
replication120 minutes

Replication Lab: Autor (2003) Wrongful Discharge Laws and Outsourcing

Replicate the event study analysis from Autor (2003) on the effect of wrongful discharge laws on temporary help employment. Construct event-time indicators, estimate dynamic treatment effects, test pre-trends, and apply the Sun-Abraham heterogeneity-robust estimator.

Overview

David Autor's 2003 paper "Outsourcing at Will: The Contribution of Unjust Dismissal Doctrine to the Growth of Temporary Employment" (Journal of Labor Economics, 21(1), 1–42; DOI: 10.1086/344122) examines how the adoption of wrongful discharge laws (specifically, the implied-contract exception to employment-at-will) affected the use of temporary help services across U.S. states. The paper uses the staggered adoption of these laws across states between the 1970s and 1990s as a natural experiment, estimating event study models to trace out the dynamic effects.

Key findings:

  • Temporary help employment increases significantly after adoption of wrongful discharge laws
  • The pre-adoption coefficients are close to zero, supporting the parallel trends assumption
  • The effect builds gradually over several years post-adoption
  • The magnitude implies that wrongful discharge laws account for a meaningful share of the rise in temporary employment

What you will learn:

  • How to construct event-time (relative time) indicators for a staggered adoption design
  • How to estimate a two-way fixed effects (TWFE) event study regression
  • How to create and interpret the event study plot
  • How to formally test for pre-trends
  • How to implement the Sun and Abraham (2021) heterogeneity-robust estimator
  • Why staggered adoption creates problems for TWFE and how to address them

Prerequisites: Difference-in-differences, fixed effects (see the DiD and FE labs).


Step 1: Generate the Simulated Panel Dataset

library(fixest)
library(modelsummary)

# Simulate state-year panel with staggered adoption
set.seed(42)
n_states <- 50
n_years <- 25
years <- 1975:1999

# Staggered adoption
adopt_year <- rep(NA, n_states)
treated_states <- sample(1:n_states, 35)
for (s in treated_states) {
adopt_year[s] <- sample(1980:1994, 1)
}

state_fe <- rnorm(n_states, 0, 0.5)
year_fe <- seq(0, 1.5, length.out = n_years)

df <- expand.grid(state = 1:n_states, year = years)
df$adopt_year <- adopt_year[df$state]
df$ever_treated <- as.integer(!is.na(df$adopt_year))
df$event_time <- ifelse(df$ever_treated == 1, df$year - df$adopt_year, NA)
df$treated_post <- as.integer(!is.na(df$adopt_year) & df$year >= df$adopt_year)

# Dynamic treatment effect
df$tau <- ifelse(df$treated_post == 1 & df$event_time >= 0,
               0.05 * pmin(df$event_time, 8) + 0.01 * df$event_time, 0)

df$y <- 2.0 + state_fe[df$state] + year_fe[df$year - 1974] +
      df$tau + rnorm(nrow(df), 0, 0.15)

cat("Panel:", n_states, "states x", n_years, "years =", nrow(df), "obs\n")
cat("Treated:", sum(!is.na(adopt_year)), "  Never-treated:", sum(is.na(adopt_year)), "\n")

Expected output:

stateyearytreated_postevent_timeadopt_yearever_treated
019751.870-12.019871
019802.150-7.019871
019902.6813.019871
3519852.5100
3519953.1200

Summary statistics:

StatisticValue
Panel dimensions50 states x 25 years = 1,250 obs
Treated states35
Never-treated states15
Adoption years1980–1994 (staggered)
Mean outcome (y)~2.0 + state FE + time trend
DGP treatment effect0.05 * min(k, 8) + 0.01 * k

Step 2: Construct Event-Time Dummies

# Create event-time dummies for TWFE
# Bin endpoints, reference period = -1
df$et <- ifelse(df$ever_treated == 1, df$event_time, NA)
df$et_binned <- pmax(pmin(df$et, 10), -6)  # Bin at -6 and +10

# For fixest, we can use the i() function directly
# But let us also create manual dummies for transparency
for (k in -6:10) {
if (k == -1) next  # reference period
varname <- paste0("et_", ifelse(k < 0, paste0("m", abs(k)), k))
if (k == -6) {
  df[[varname]] <- as.integer(df$ever_treated == 1 & df$et <= k)
} else if (k == 10) {
  df[[varname]] <- as.integer(df$ever_treated == 1 & df$et >= k)
} else {
  df[[varname]] <- as.integer(df$ever_treated == 1 & df$et == k)
}
}

cat("Event-time dummies created. Reference period: t = -1\n")
Requiresfixest

Expected output:

Event-time indicatorDescriptionObservations
et_m6 (k <= -6)Binned pre-period~210 (treated obs 6+ years before)
et_m5 (k = -5)5 years before adoption~35
et_m4 (k = -4)4 years before~35
et_m3 (k = -3)3 years before~35
et_m2 (k = -2)2 years before~35
k = -1Reference (omitted)
et_0 (k = 0)Year of adoption~35
et_1 to et_91–9 years after~35 each
et_10 (k >= 10)Binned post-period~175 (treated obs 10+ years after)

Step 3: Estimate the TWFE Event Study

# TWFE Event Study using fixest
# fixest handles event studies elegantly with i() syntax
es_model <- feols(y ~ i(et_binned, ever_treated, ref = -1) |
                state + year, data = df,
                cluster = ~state)

summary(es_model)

# The coefficients are automatically named by event time
Requiresfixest

Expected output:

Event Time (k)TWFE CoefficientSETrue Effect (DGP)
-6 (binned)~0.000.040
-5~0.010.050
-4-0.010.050
-30.020.050
-2-0.010.050
-1 (ref)0.000--0
0~0.060.050.05
1~0.110.050.11
2~0.170.050.17
3~0.230.050.23
4~0.290.050.29
5~0.350.050.35
6~0.410.060.41
7~0.470.060.47
8~0.480.060.48
9~0.490.060.49
10 (binned)~0.500.050.50+

The DGP treatment effect is tau = 0.05 * min(k, 8) + 0.01 * k. Post-treatment coefficients should rise steadily, leveling off around k = 8 where the 0.05-per-year component caps.


Step 4: Plot the Event Study Coefficients

# Event study plot using fixest
iplot(es_model,
    main = "Event Study: Wrongful Discharge Laws and Temp Employment",
    xlab = "Event Time (years relative to adoption)",
    ylab = "Coefficient (relative to t = -1)")
abline(v = -0.5, col = "red", lty = 2)

# Alternative: manual plot
coefs <- coef(es_model)
ses <- se(es_model)
# Extract event times from coefficient names
# (fixest names them automatically)
Requiresfixest

Step 5: Formal Pre-Trends Test

# Joint test of pre-trends using fixest::wald
# Test that all pre-treatment coefficients are jointly zero
pre_test <- wald(es_model, "et_binned::-[2-6]")
print(pre_test)

# Alternative: manual F-test
# Get pre-treatment coefficient names
pre_names <- grep("et_binned::-[2-6]", names(coef(es_model)), value = TRUE)
if (length(pre_names) > 0) {
linearHypothesis_result <- car::linearHypothesis(es_model, pre_names)
print(linearHypothesis_result)
}
Requiresfixestcar

Expected output:

StatisticValue
H0All pre-treatment coefficients = 0
Wald chi-squared~2.0–6.0
Degrees of freedom5 (testing k = -6 through k = -2)
p-value> 0.05 (typically 0.3–0.8)
ConclusionPASS: Cannot reject flat pre-trends
Pre-trend coefficientEstimatet-statistic
et_m6~0.00~0.1
et_m5~0.01~0.2
et_m4~-0.01~-0.2
et_m3~0.02~0.4
et_m2~-0.01~-0.2

All individual pre-treatment coefficients are small and statistically insignificant (|t| < 1.96).

Concept Check

The joint pre-trends test fails to reject the null (p > 0.05). Does this prove that the parallel trends assumption holds?


Step 6: Sun-Abraham Heterogeneity-Robust Estimator

Recent research by Sun and Abraham (2021) shows that TWFE event study estimates can be biased under treatment effect heterogeneity across cohorts. The Sun-Abraham estimator provides a heterogeneity-robust alternative.

# Sun-Abraham estimator using fixest
# fixest implements this with sunab()
df$cohort <- ifelse(is.na(df$adopt_year), 10000, df$adopt_year)  # Never-treated = Inf

sa_model <- feols(y ~ sunab(cohort, year) | state + year,
                data = df[df$cohort != 10000 | df$ever_treated == 0, ],
                cluster = ~state)

summary(sa_model)

# Compare TWFE and Sun-Abraham plots
par(mfrow = c(1, 2))
iplot(es_model, main = "TWFE Event Study")
iplot(sa_model, main = "Sun-Abraham Event Study")

# Aggregate Sun-Abraham estimates
summary(sa_model, agg = "att")
Requiresfixest

Expected output:

Event Time (k)TWFE CoefficientSun-Abraham Coefficient
-6~0.00~0.00
-4~-0.01~-0.01
-2~-0.01~-0.01
-1 (ref)0.0000.000
0~0.06~0.06
2~0.17~0.17
5~0.35~0.36
8~0.48~0.49
10~0.50~0.51

With the relatively homogeneous treatment effects in this DGP, the TWFE and Sun-Abraham estimates should be very similar. With real data exhibiting treatment effect heterogeneity across cohorts, larger differences would emerge.

Concept Check

In a staggered adoption design, the TWFE estimator can produce biased estimates of the event study coefficients. Which of the following is the key reason?


Step 7: Compare with Published Results

Key comparisons with Autor (2003):

FeatureAutor (2003)Our Simulation
Pre-trendsFlat (insignificant)Check your pre-trend test
Post-treatment effectPositive, growingCheck your event study plot
Effect builds over timeYes (gradual)Should match our DGP
State + year FEYesYes
Clustered SEAt state levelAt state level

The central finding is that wrongful discharge laws cause an increase in temporary employment, with the effect building gradually over several years. The pre-treatment coefficients should be close to zero, supporting the parallel trends assumption.


Extension Exercises

  1. Callaway-Sant'Anna estimator. Implement the Callaway and Sant'Anna (2021) estimator using the did package in R or csdid in Stata. Compare the group-time ATT estimates with the TWFE results.

  2. Treatment effect heterogeneity. Modify the DGP so that early adopters have larger treatment effects than late adopters. Re-estimate the TWFE event study and the Sun-Abraham estimator. How much does the bias in TWFE increase?

  3. Anticipation effects. Add anticipation effects to the DGP (effects begin 1-2 years before formal adoption, as states may announce laws before enacting them). How does this affect the pre-trends test and the estimated treatment effects?

  4. Bacon decomposition. Implement the Goodman-Bacon (2021) decomposition to understand the weights TWFE places on different 2x2 DiD comparisons. Which comparisons receive negative weights?

  5. Wild cluster bootstrap. With only 50 clusters, asymptotic cluster-robust inference may be unreliable. Implement the wild cluster bootstrap ((Cameron et al., 2008)) and compare confidence intervals with the conventional clustered SEs.


Summary

In this replication lab you learned:

  • Event study designs trace out dynamic treatment effects and provide a visual test of parallel trends
  • The reference period (t = -1) is conventional; all coefficients are relative to the period just before treatment
  • Flat pre-treatment coefficients are necessary (but not sufficient) for the parallel trends assumption
  • Standard TWFE event studies can be biased under staggered adoption with heterogeneous treatment effects
  • The Sun and Abraham (2021) estimator avoids "forbidden comparisons" by estimating cohort-specific effects and aggregating them with proper weights
  • Our simulated results reproduce the key pattern from Autor (2003): flat pre-trends followed by a gradual increase in temporary employment after wrongful discharge law adoption
  • It is recommended to report the event study plot, pre-trends test, and sensitivity to alternative estimators