← All examples
62

Canonical Grid model

Economics - Inference and difference-in-differences starter

Synthetic covariance comparison and a separate two-period policy experiment with explicit identification assumptions.

Scale
Small
Source
economics-inference-starter.grid
Length
62 lines
Collection
Advanced language
Level
Intermediate
Runtime
Portable
Version
1.0.0
economics-inference-starter.grid
Get Grid
MODEL "Economics - Inference and difference-in-differences starter"
DESCRIPTION "Synthetic covariance comparison and a separate two-period policy experiment with explicit identification assumptions."
VERSION "1.0.0"
AUTHOR "Grid"
TAGS "economics", "econometrics", "starter"

# Shared reporting choices and synthetic policy effect
input Confidence = 0.95
  VALIDATE BETWEEN 0.8 AND 0.999 MESSAGE "Choose a confidence fraction between 0.8 and 0.999."
input PolicyEffect = 2
  VALIDATE BETWEEN -5 AND 5 MESSAGE "Choose a synthetic policy effect between -5 and 5."

# One ordered illustrative series, with two predictors and eight four-observation blocks.
Period = SEQUENCE(1, 32)
Block = MAP(Period, (period) => INT((period - 1) / 4) + 1)
SeriesOutcome = MAP(Period, (period) => 5 + 0.3 * period + 0.8 * SIN(period * PI() / 4) + (0.25 + period / 160) * COS(period * PI() / 3) + 0.15 * (2 * MOD(INT((period - 1) / 4), 2) - 1))
SeriesDesign = MAKEARRAY(32, 2, (row, column) => column = 1 THEN row ELSE SIN(row * PI() / 4))
SeriesLabels = {termNames: ["Constant", "Time trend", "Seasonal exposure"]}
ClusterLabels = {inference: "cluster_t", termNames: ["Constant", "Time trend", "Seasonal exposure"]}
HacLabels = {inference: "normal", termNames: ["Constant", "Time trend", "Seasonal exposure"]}
Classical = REGRESS(SeriesOutcome, SeriesDesign, "classical", 0, TRUE, Confidence, SeriesLabels)
Heteroskedastic = REGRESS(SeriesOutcome, SeriesDesign, "hc1", 0, TRUE, Confidence, SeriesLabels)
Clustered = REGRESS(SeriesOutcome, SeriesDesign, "cluster", Block, TRUE, Confidence, ClusterLabels)
TimeDependent = REGRESS(SeriesOutcome, SeriesDesign, "newey_west", 2, TRUE, Confidence, HacLabels)

# Twenty synthetic groups, observed before and after a common adoption date.
ObservationPosition = SEQUENCE(1, 40)
ClusterId = MAP(ObservationPosition, (position) => INT((position - 1) / 2) + 1)
Post = MAP(ObservationPosition, (position) => MOD(position - 1, 2))
Treated = MAP(ClusterId, (cluster) => cluster > 10 THEN 1 ELSE 0)
PolicyOutcome = MAP(ClusterId, Post, Treated, (cluster, post, treated) => 10 + 0.2 * cluster + 1.5 * post + PolicyEffect * post * treated + 0.2 * (2 * MOD(cluster, 2) - 1) * post)
PolicyDesign = MAKEARRAY(40, 3, (row, column) => column = 1 THEN INDEX(Treated, 1, row) ELSE column = 2 THEN INDEX(Post, 1, row) ELSE INDEX(Treated, 1, row) * INDEX(Post, 1, row))
PolicyLabels = {inference: "cluster_t", termNames: ["Constant", "Treated cluster", "Post period", "Treatment x post"]}
PolicyFit = REGRESS(PolicyOutcome, PolicyDesign, "cluster", ClusterId, TRUE, Confidence, PolicyLabels)

output CovarianceComparison = REGRESS.TABLE(Classical, Heteroskedastic, Clustered, TimeDependent)
output PolicyComparison = REGRESS.TABLE(PolicyFit)
output EstimatedPolicyEffect = INDEX(PolicyFit.coefficients, 1, 4)
output PolicyStandardError = INDEX(PolicyFit.standardErrors, 1, 4)
output PolicyInferenceDegrees = PolicyFit.inferenceDf
output SameOlsCoefficients = ASSERT_IDENTITY(Classical.coefficients, Clustered.coefficients)
output SyntheticEffectCheck = ASSERT_IDENTITY(EstimatedPolicyEffect, PolicyEffect)
output CovarianceAssumptions = "These four covariance methods impose different dependence assumptions; the example does not select the appropriate method for real data. Eight clusters are few. Newey-West uses the ordered series with two lags and a normal reference; it is not applied to arbitrarily ordered panel rows."
output IdentificationAssumptions = "The synthetic DID has a common treatment date, parallel average untreated changes, no anticipation and no spillovers. Two dates cannot establish a pre-trend. Twenty groups are still a small cluster sample; a significant coefficient does not establish these assumptions."

A1 = "Inference"
A2 = "Covariances"
B2 = CovarianceComparison
A5 = "DID table"
B5 = PolicyComparison
B7 = "Effect"
C7 = "Cluster SE"
A8 = "DID results"
B8 = EstimatedPolicyEffect
C8 = PolicyStandardError
A9 = "Inference df"
B9 = PolicyInferenceDegrees
A11 = "Effect check"
B11 = SyntheticEffectCheck
A12 = "OLS check"
B12 = SameOlsCoefficients
END MODEL