name: r-econometrics description: Run IV, DiD, and RDD analyses in R with proper diagnostics workflow_stage: analysis compatibility:
- claude-code
- cursor
- codex
- gemini-cli author: Awesome Econ AI Community version: 1.1.0 tags:
- R
- econometrics
- causal-inference
- fixest
- regression
R Econometrics
Purpose
This skill helps economists run rigorous econometric analyses in R, including Instrumental Variables (IV), Difference-in-Differences (DiD), and Regression Discontinuity Design (RDD). It generates publication-ready code with proper diagnostics and robust standard errors.
When to Use
- Running causal inference analyses
- Estimating treatment effects with panel data
- Creating publication-ready regression tables
- Implementing modern econometric methods (two-way fixed effects, event studies)
Instructions
Step 1: Understand the Research Design
Before generating code, ask the user:
- What is your identification strategy? (IV, DiD, RDD, or simple regression)
- What is the unit of observation? (individual, firm, country-year, etc.)
- What fixed effects do you need? (entity, time, two-way)
- How should standard errors be clustered?
Step 2: Look at the Panel Data Before Estimating
"When I have not looked at my data, I have little imagination about the DGP. No model, however good, can fix that." — Yiqing Xu, Please look at your (panel) data
Visualizing the panel structure should be routine, not optional. Before generating any regression code, produce and read a treatment-status plot with the panelView package. Every cell must be uniquely identified by a unit-time pair — if it is not, stop and resolve the unit of analysis first.
library(panelView)
# Treatment-status pattern: who is treated, when they switch on, and what's missing
panelview(outcome ~ treatment,
data = df, index = c("unit", "time"),
main = "Treatment status pattern",
by.timing = TRUE) # sort units by adoption timing
# Outcome trajectories: distribution, outliers, treated/control overlap, persistence
panelview(outcome ~ treatment,
data = df, index = c("unit", "time"),
type = "outcome")
Use these plots to answer three questions before trusting any estimate:
- Where does the identifying variation actually come from? With fixed effects, the coefficients come from variation left after the FEs are absorbed. If treatment varies almost entirely along one dimension (only across units, or only across time), TWFE will soak up nearly all of it and leave very thin identifying variation. Watch for singletons — observations alone in a FE group; they have no within-group variation, get dropped, and contribute nothing.
- What is the effective number of observations? A panel of 1,001 units with 1 treated unit does not have an effective sample size of 1,001. Uncertainty is driven by the treated cells; gauge how many cells truly carry the estimate.
- What does the missing-data pattern look like? Plot treatment status alongside missingness. Severe or systematic missingness means MCAR/MAR assumptions are far stronger than usually acknowledged — flag this as a threat to the results rather than ignoring it.
For modern DID estimators, visualize which cells actually participate in estimation (supported by fect and PanelMatch), since only a strict subset of the panel contributes once you fix matching/lag/lead windows:
# PanelMatch example: mask the panel to the cells that drive the estimate
panelview(data = pd, formula = y ~ treatment,
index = c("unit", "time"), type = "treat",
by.timing = TRUE, sample = pm_object)
Caution on terminology: a treatment-status plot is not a treatment assignment, let alone a design. The same staggered pattern can arise from very different assignment processes — treat staggered adoption as a setting, not a "design," unless it really is a stepped-wedge trial.
Step 3: Generate Analysis Code
Based on the research design, generate R code that:
- Uses the
fixestpackage - Modern, fast, and feature-rich for panel data - Includes proper diagnostics:
- For IV: First-stage F-statistics, weak instrument tests
- For DiD: Parallel trends visualization, event study plots
- For RDD: Bandwidth selection, density tests
- Uses robust/clustered standard errors appropriate for the data structure
- Creates publication-ready output using
modelsummaryoretable
Step 4: Structure the Output
Always include:
# 1. Setup and packages
# 2. Data loading and preparation
# 3. Look at the panel (panelView: treatment status, outcomes, missingness)
# 4. Descriptive statistics
# 5. Main specification
# 6. Robustness checks
# 7. Visualization
# 8. Export results
Step 5: Add Documentation
Include comments explaining:
- Why each specification choice was made
- Interpretation of key coefficients
- Limitations and assumptions
Example Prompts
- "Run a DiD analysis with state and year fixed effects, clustering at the state level"
- "Estimate the effect of X on Y using Z as an instrument"
- "Create an event study plot showing treatment effects by year"
- "Run a sharp RDD with optimal bandwidth selection"
Example Output
# ============================================
# Difference-in-Differences Analysis
# ============================================
# Setup
library(tidyverse)
library(fixest)
library(modelsummary)
# Load data
df <- read_csv("data.csv")
# Prepare treatment variable
df <- df %>%
mutate(
post = year >= treatment_year,
treated = state %in% treatment_states,
treat_post = treated * post
)
# ----------------------------------------
# Main DiD Specification
# ----------------------------------------
# Two-way fixed effects
did_model <- feols(
outcome ~ treat_post | state + year,
data = df,
cluster = ~state
)
# View results
summary(did_model)
# ----------------------------------------
# Event Study
# ----------------------------------------
# Create relative time variable
df <- df %>%
mutate(rel_time = year - treatment_year)
# Event study regression
event_study <- feols(
outcome ~ i(rel_time, treated, ref = -1) | state + year,
data = df,
cluster = ~state
)
# Plot coefficients
iplot(event_study,
main = "Event Study: Effect on Outcome",
xlab = "Years Relative to Treatment")
# ----------------------------------------
# Robustness: Alternative Specifications
# ----------------------------------------
# Different clustering
did_robust <- feols(
outcome ~ treat_post | state + year,
data = df,
cluster = ~state + year # Two-way clustering
)
# ----------------------------------------
# Export Results
# ----------------------------------------
modelsummary(
list("Main" = did_model, "Two-way Cluster" = did_robust),
stars = c('*' = 0.1, '**' = 0.05, '***' = 0.01),
output = "results/did_table.tex"
)
Requirements
Software
- R 4.0+
Packages
panelView- Visualize panel/treatment structure before estimatingfixest- Fast fixed effects estimationmodelsummary- Publication-ready tablestidyverse- Data manipulationggplot2- Visualization
Install with:
install.packages(c("panelView", "fixest", "modelsummary", "tidyverse"))
Best Practices
- Look at the panel before you estimate — plot treatment status, outcome trajectories, and missingness with
panelView; include these plots for reviewers, who usually can't see the data - Ensure every cell is uniquely identified by a unit-time pair before running anything
- Always cluster standard errors at the level of treatment assignment
- Run pre-trend tests for DiD designs
- Report first-stage F-statistics for IV (should be > 10)
- Use
feolsoverlmfor panel data (faster and more features) - Document all specification choices in your code comments
Common Pitfalls
- ❌ Running regressions without ever looking at the panel structure
- ❌ Fitting TWFE when treatment varies along only one dimension (identifying variation is nearly absorbed)
- ❌ Ignoring singletons and severe/systematic missingness (MCAR/MAR assumptions are stronger than they look)
- ❌ Calling a staggered-adoption setting a "design" when assignment is observational
- ❌ Not clustering standard errors at the right level
- ❌ Ignoring weak instruments in IV estimation
- ❌ Using TWFE with staggered treatment timing (use
didorsunab()instead) - ❌ Not reporting robustness checks
References
- panelView documentation
- Xu (2026) Please look at your (panel) data
- fixest documentation
- Cunningham (2021) Causal Inference: The Mixtape
- Angrist & Pischke (2009) Mostly Harmless Econometrics
Changelog
v1.1.0
- Added "Look at the panel data before estimating" step (panelView): treatment-status, outcome-trajectory, and missingness plots; participating-cells visualization for
fect/PanelMatch. Based on Yiqing Xu (2026).
v1.0.0
- Initial release with IV, DiD, RDD support
Ingénierie de Prompts
Data & IA
Bonnes pratiques et templates de prompt engineering pour maximiser les résultats IA.
Visualisation de Données
Data & IA
Génère des visualisations de données et graphiques adaptés à vos données.
Architecture RAG
Data & IA
Guide de configuration d'architectures RAG (Retrieval-Augmented Generation).