Visualize the results of an emfx
call.
Arguments
- x
An
emfx
object.- type
Character. The type of plot display. One of
"pointrange"
(default),"errorbar"
, or"ribbon"
.- pch
Integer or character. Which plotting character or symbol to use (see
points
). Defaults to 16 (i.e., small solid circle). Ignored iftype = "ribbon"
.- zero
Logical. Should 0-zero line be emphasized? Default is
TRUE
.- grid
Logical. Should a background grid be displayed? Default is
TRUE
.- ref
Integer. Reference line marker for event-study plot. Default is
-1
(i.e., the period immediately preceding treatment). To remove completely, set toNA
,NULL
, orFALSE
. Only used if the underlying object was computed usingemfx(..., type = "event")
.- ...
Additional arguments passed to
tinyplot::tinyplot
.
Examples
# \dontrun{
# We’ll use the mpdta dataset from the did package (which you’ll need to
# install separately).
# install.packages("did")
data("mpdta", package = "did")
#
# Basic example
#
# The basic ETWFE workflow involves two consecutive function calls:
# 1) `etwfe` and 2) `emfx`
# 1) `etwfe`: Estimate a regression model with saturated interaction terms.
mod = etwfe(
fml = lemp ~ lpop, # outcome ~ controls (use 0 or 1 if none)
tvar = year, # time variable
gvar = first.treat, # group variable
data = mpdta, # dataset
vcov = ~countyreal # vcov adjustment (here: clustered by county)
)
# mod ## A fixest model object with fully saturated interaction effects.
# 2) `emfx`: Recover the treatment effects of interest.
(mod_es = emfx(mod, type = "event")) # dynamic ATE a la an event study
#>
#> Term event Estimate Std. Error z Pr(>|z|) S 2.5 % 97.5 %
#> .Dtreat 0 -0.0332 0.0134 -2.48 0.013 6.3 -0.0594 -0.00701
#> .Dtreat 1 -0.0573 0.0172 -3.34 <0.001 10.2 -0.0910 -0.02373
#> .Dtreat 2 -0.1379 0.0308 -4.48 <0.001 17.0 -0.1982 -0.07751
#> .Dtreat 3 -0.1095 0.0323 -3.39 <0.001 10.5 -0.1729 -0.04619
#>
#> Type: response
#> Comparison: TRUE - FALSE
#> Columns: term, contrast, event, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high
#>
# Etc. Other aggregation type options are "simple" (the default), "group"
# and "calendar"
# To visualize results, use the native plot method (see `?plot.emfx`)
plot(mod_es)
# Notice that we don't get any pre-treatment effects with the default
# "notyet" treated control group. Switch to the "never" treated control
# group if you want this.
etwfe(
lemp ~ lpop, tvar = year, gvar = first.treat, data = mpdta,
vcov = ~countyreal,
cgroup = "never" ## <= use never treated group as control
) |>
emfx("event") |>
plot()
#
# Heterogeneous treatment effects
#
# Example where we estimate heterogeneous treatment effects for counties
# within the 8 US Great Lake states (versus all other counties).
gls = c("IL" = 17, "IN" = 18, "MI" = 26, "MN" = 27,
"NY" = 36, "OH" = 39, "PA" = 42, "WI" = 55)
mpdta$gls = substr(mpdta$countyreal, 1, 2) %in% gls
hmod = etwfe(
lemp ~ lpop, tvar = year, gvar = first.treat, data = mpdta,
vcov = ~countyreal,
xvar = gls ## <= het. TEs by gls
)
# Heterogeneous ATEs (could also specify "event", etc.)
emfx(hmod)
#>
#> Term .Dtreat gls Estimate Std. Error z Pr(>|z|) S 2.5 % 97.5 %
#> .Dtreat TRUE FALSE -0.0637 0.0376 -1.69 0.0906 3.5 -0.137 0.01007
#> .Dtreat TRUE TRUE -0.0472 0.0271 -1.74 0.0817 3.6 -0.100 0.00594
#>
#> Type: response
#> Comparison: TRUE - FALSE
#> Columns: term, contrast, .Dtreat, gls, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high
#>
# To test whether the ATEs across these two groups (non-GLS vs GLS) are
# statistically different, simply pass an appropriate "hypothesis" argument.
emfx(hmod, hypothesis = "b1 = b2")
#>
#> Term Estimate Std. Error z Pr(>|z|) S 2.5 % 97.5 %
#> b1=b2 -0.0164 0.0559 -0.294 0.769 0.4 -0.126 0.093
#>
#> Type: response
#> Columns: term, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high
#>
plot(emfx(hmod))
#
# Nonlinear model (distribution / link) families
#
# Poisson example
mpdta$emp = exp(mpdta$lemp)
etwfe(
emp ~ lpop, tvar = year, gvar = first.treat, data = mpdta,
vcov = ~countyreal,
family = "poisson" ## <= family arg for nonlinear options
) |>
emfx("event")
#> The variables '.Dtreat:first.treat::2006:year::2004', '.Dtreat:first.treat::2006:year::2005', '.Dtreat:first.treat::2007:year::2004', '.Dtreat:first.treat::2007:year::2005', '.Dtreat:first.treat::2007:year::2006', '.Dtreat:first.treat::2006:year::2004:lpop_dm' and 4 others have been removed because of collinearity (see $collin.var).
#>
#> Term event Estimate Std. Error z Pr(>|z|) S 2.5 % 97.5 %
#> .Dtreat 0 -25.35 15.9 -1.5942 0.111 3.2 -56.5 5.82
#> .Dtreat 1 1.09 41.8 0.0261 0.979 0.0 -80.9 83.09
#> .Dtreat 2 -75.12 22.3 -3.3696 <0.001 10.4 -118.8 -31.43
#> .Dtreat 3 -101.82 28.1 -3.6234 <0.001 11.7 -156.9 -46.75
#>
#> Type: response
#> Comparison: TRUE - FALSE
#> Columns: term, contrast, event, estimate, std.error, statistic, p.value, s.value, conf.low, conf.high
#>
# }