The didFF R package assesses when the validity of difference-in-differences and related estimators depends on functional form, based on the theoretical results in Roth and Sant’Anna (2022). This package provides a test for whether parallel trends is insensitive to functional form by estimating the implied density of potential outcomes under the null and checking if it is significantly below zero at some point.
You can install the development version of didFF from GitHub with:
#Install the devtools package if not already installed
# install.packages("devtools")
#Install the didFF package using devtools
devtools::install_github("amenabrown/didFF")
We now provide and example of how to use the package using the empirical illustration from Roth and Sant’Anna (2022, p.11).
We first load the package and the data.
library(didFF) #load the TestFunctional Form package
mw_df<-didFF::mw_df #load Cengiz et al. (2019) data frame
The data is derived from the dataset compiled by Cengiz et al. (2019). For each state and year, it provides the number of people employed at each wage level (coarsened to 25c bins), with a value of 0 for people not in the labor force. It also contains an indicator variables (treated) for whether a state raised its minimum wage in the given year.
head(mw_df, 5)
#> statenum year wage treated pop
#> 1 1 1979 0.00 0 1463246.6238
#> 2 1 1979 1.00 0 0.0000
#> 3 1 1979 1.25 0 415.0158
#> 4 1 1979 1.50 0 777.4267
#> 5 1 1979 1.75 0 0.0000
We will now test whether a DiD analysis for the effect of the minimum wage on wages (weighted by population) is insensitive to functional form – i.e. that parallel trends is valid regardless of whether wages are measured in levels, logs, percentiles, etc. We first consider an analysis where the pre-treatment period is 2007, the post-treatment period is 2015, and the treatment is whether a state raised its minimum wage at any point between the pre-treatment and post-treatment periods. (By default, didFF considers a unit to be treated in a given window if it is treated at any point between the provided start and end years.) We call didFF as follows:
test_2007_2015<-didFF(
DF=mw_df,
idvar="statenum", #panel id is state
yvar="wage", #outcome is wage
tvar="year", #time period is year
treatmentvar = "treated", #treatment indicator
weight = "pop", #weight by population in each bin
start_t=2007, #pre-treatment year
end_t=2015, #post-treatment year
lb_graph=5,
ub_graph=29.99
)
test_2007_2015$plot
The plot shows the implied counterfactual density for the treated group if parallel trends holds for all functional forms of the outcome, which Roth and Sant’Anna show is equivalent to “parallel trends of distributions”. (To preserve reasonable scaling, we use the options minbin and maxbin so that the plot shows only wages above 5 and below 30). The figure shows that the implied density is negative for wages between approximately $5-7/hour.
The plot also shows a formal p-value for the null hypothesis that parallel trends holds for all functional forms (this is calculated using a “least-favorable” critical value for moment inequalities, as in, e.g., Section 4.1.1 of Canay and Shaikh (2017)). The test shows that we are able to reject the null hypothesis that all of the implied densities are positive (p<0.001). We thus reject the null that parallel trends hold for all functional forms of the outcome.
By contrast, results using the period 2010-2015 shows that the estimated counterfactual distribution has positive density nearly everywhere, and we cannot formally reject the hypothesis that it is positive everywhere (p=0.293). This does not necessarily imply that parallel trends holds for all transformations of the outcome, but insensitivity to functional form is not rejected by the data in this example.
test_2010_2015<-didFF(DF=mw_df,
idvar="statenum", #panel id is state
yvar="wage", #outcome is wage
tvar="year", #time period is year
treatmentvar = "treated", #treatment indicator
weight = "pop", #weight by population in each bin
start_t=2010, #pre-treatment year
end_t=2015, #post-treatment year
lb_graph=5,
ub_graph=29.99
)
test_2010_2015$plot