*! version 1.1.1 31mar2022

Title

pzms -- implements the Placebo Zone optimal Model Selection algorithm for regression discontinuity and kink designs proposed in Kettlewell & Siminski (2022).

Syntax

pzms
depvar runvar
[if] [in]
, maxbw(real) [options]

Required
maxbw(#) the maximum bandwidth considered for estimation

Optional
c(#) the cut-off threshold for the treatment

minbw(#) the minimum bandwidth considered for estimation

pzrange(# #) the range for the placebo zone

p(#) the polynomial orders to be considered for estimation

deriv(#) specifies the order of the derivative of the regression functions to be estimated

pzstepnum(#) the number of placebo zone iterations to be performed

pzstepsize(#) the distance between consecutive placebo thresholds

bwstepnum(#) the number of bandwidths to be considered between minbw and maxbw

bwstepsize(#) the increase in bandwidth between candidate estimators

nolog suppresses the display of iterations count

vce(string) specifies the vce type for standard errors

covs(varlist) covariates that will be included in the models compared

kernel(string) specifies the type of kernel weights to be applied

weight(varname) specifies the analytical weights to be applied

collapse(string) allows the dataset to be collapsed at the level of runvar before estimation

bwlfix(#) fixes the bandwidth on the left of the cut-off to this value

bwrfix(#) fixes the bandwidth on the right of the cut-off to this value

donut(# #) drops observations within the specified range of the cut-off

pzplot generate a kernel density plot of the placebo zone estimates

mcustom#(# #, mcustom_options) allows the user to specify custom candidate specifications

Description

pzms implements the placebo zone model selection algorithm for regression discontinuity (RDD) and kink (RKD) designs proposed in
Kettlewell & Siminski (2022). It also reports regression estimates using the model specification selected by the algorithm.
The pzms algorithm works by estimating treatment effects for candidate RDD or RKD specifications at various 'placebo thresholds'. These placebo
thresholds are cut-off points along the range of the running variable where there is no actual discrete change in treatment (this region is described
as the placebo zone). Treatment effects are assumed to be zero at these thresholds. Candidate models can vary by combinations of bandwidth, polynomial
order, kernel weighting, analytical weighting and covariates. The candidate specification with the lowest root mean squared error of placebo estimates
is selected as the preferred specification.

Options

maxbw(#) the maximum bandwidth considered when comparing specifications throughout the placebo zone. There is no default.

c(#) the cut-off threshold for the treatment. The default is zero.

minbw(#) the minimum bandwidth considered when comparing specifications throughout the placebo zone.
If this is not specified, it will be set at 0.1*maxbw.

pzrange(# #) the range of the placebo zone, which must include c(#) in its interior. The default is the full range of the running variable.

p(#) polynomial order for the RDD/RKD candidate specifications. Under the default (1) pzms will consider linear candidate specifications. If 2
is specified, pzms will consider both linear and quadratic specifications.

deriv(#) specifies the order of the derivative of the candidate specifications. 0 (default) is for sharp RDD
and 1 is for sharp RKD.

pzstepnum(#) specifies the number of placebo zone iterations to be performed. There may be less iterations than specified by pzstepnum(#) if some
steps are too small to move to a new placebo threshold (this may occur when the running variable is sparse, or when pzstepnum is very high). It is
therefore a maximum number of iterations. pzstepnum cannot be used if pzstepsize is also specified. The default is 50 if neither pzstepnum or pzstepsize
are specified.

pzstepsize(#) specifies the the distance between consecutive placebo thresholds. pzstepsize cannot be used if pzstepnum is also specified.
See also pzstepnum.

bwstepnum(#) the number of bandwidths to be considered between minbw and maxbw. The default is 20 if neither bwstepnum or
bwstepsize are specified.

bwstepsize(#) the increase in bandwidth (in units of the running variable) between the candidate estimators considered. See also bwstepnum.

nolog if specified, an iteration log will not be displayed as the algorithm works through the placebo zone.

vce(vce type) this allows the user to specify the type of standard errors. Any vce that is available for the Stata command regress can
be used (ols, robust, cluster clustvar, bootstrap, jackknife, hc2, or hc3). The default is homoscedastic standard errors.

covs(varlist) specifies the covariates to include in the candidate specifications. If this option is chosen, the algorithm
will estimate a model for each level of polynomial p(#), with and without the covariates. For example, if p(2) is specified, there will be
four models compared – linear without covariates, linear with covariates, quadratic without covariates and quadratic with covariates.

kernel(kernel type) allows the user to choose what sort of kernel weights to apply. uniform and triangular are
supported. The default is uniform.

weight(varname) is used to specify analytical weights [aweights]. The weights will apply to every model considered
except the models specified in mcustom#.

collapse(string) this will collapse the data at the level of the running variable before implementing the algorithm. If collapse(weight)
is specified, the estimates will be weighted by the number of observations corresponding to the collapsed bins. This will usually be desired. Use
collapse(noweight) if you do not want to use weights for observation frequency when the data are collapsed. The collapse option can greatly
improve speed when the running variable is discrete and there are many observations and/or placebo zone iterations, without affecting the estimates.
The collapse option can be combined with the weight option if you want to apply additional analytical weights, even if collapse(weight) is specified.

bwlfix(#) this option allows the user to fix the length of the bandwidth on the left hand side of the threshold. It may be helpful if the
candidate set of specifications is constrained by the data such that you can only accommodate short bandwidths on the left but much longer on the
right, or to explore the performance of asymmetric bandwidths.

bwrfix(#) this option allows the user to fix the length of the bandwidth on the right hand side of the threshold. It may be helpful if the candidate
set of specifications is constrained by the data such that you can only accommodate short bandwidths on the right but much longer on the left, or to
explore the performance of asymmetric bandwidths.

pzplot a kernel density plot will be produced that summarises the distribution of placebo estimates from the winning specification. The plot
uses Stata's kdensity command with default settings.

donut(# #) drops observations within the specified range of the cut-off. The first # specifies that observations within this value of the running
variable to the left of the cut-off be dropped. The second # specifies that observations within this value of therunning variable to the right of the
cut-off be dropped. This option can be used as an ad hoc solution to threshold bunching or other non-compliance issues.

mcustom#(# #, mcustom_options) this allows the user to include additional specifications in the candidate set with custom features. You can
specify up to 10 custom models by using mcustom1(), mcustom2() etc. This first argument in mcustom is the polynomial order on the left of the
treatment threshold and the second argument is the polynomial order on the right. For example, if we wanted to estimate a model that is linear on the
left and quadratic on the right, we would specify mcustom(1 2). Polynomials of any order (including zero) up to 10 are allowed.

mcustom_options

covs(varlist) specifies covariates that you would like to include in the custom specification.

kernel(kernal type) allows the user to choose what sort of kernel weights to apply in the custom specification. uniform and
triangular are supported. The default is uniform.

weight(varname) is used to specify analytical weights [aweights] in the custom specification.

Remarks

If you find any bugs, have questions, or want to provide feedback, please get in touch with us at Nathan.Kettlewell@uts.edu and Peter.Siminski@uts.edu.au.

Warning regarding default settings: While we have tried to select defaults that are reasonable, based on our experience with the algorithm, we strongly
recommend you consider whether these are appropriate for your application. In particular, you may want to specify pzstepsize to be equal to the
minimum change in the value of the running variable across the placebo zone, if it is feasible to do so. For example, if the running variable is measured
in days, and there are observations for every day, specifying pzstepsize(1) will ensure you are considering the maximum number of placebo
thresholds. You may also want to apply the same criteria in specifying bwstepsize. If computation is slow, the collapse option might help.

Examples

Load example dataset.

. use pzms_example_data.dta, clear

Perform model selection and estimation using default settings.

. pzms y x, maxbw(0.99)

Now consider polynomials up to order 2 and cluster standard errors.

. pzms y x, maxbw(0.99) p(2) vce(cluster x)

Increase the number of bandwidths considered and plabebo thresholds used.

. pzms y x, maxbw(0.99) p(2) vce(cluster x) bwstepnum(25) pzstepsize(0.02)

Also consider a custom linear specification with triangular kernel, and plot placebo estimates from winning specification.

. pzms y x, maxbw(0.99) p(2) vce(cluster x) bwstepnum(25) pzstepsize(0.02) mcustom(1 1, kernel(triangular)) pzplot

Stored results

Scalars

e(pz_est) the treatment effect estimate from the optimal specification

e(pz_se) the conventional standard error for the treatment effect estimate

e(pz_p) the p-value for the treatment effect using conventional standard error

e(pz_ess) the lower bound estimated effective sample size of the placebo estimates

e(pz_ess_sum) the upper bound estimated effective sample size of the placebo estimates

e(pz_altp) lower bound p-value using Kettlewell & Siminksi (2022) randomization inference method

e(pz_alt_se) the standard error using Kettlewell & Siminksi (2022) randomization inference method

e(pz_altp_sum) upper bound p-value using Kettlewell & Siminksi (2022) randomization inference method

e(pz_rmse) RMSE of optimal specification in the placebo trials

e(pz_winbw) the bandwidth of the optimal specification

e(pz_bwstepsize) the value used for bwstepsize

e(pz_pzstepsize) the value used for pzstepsize

Matrices

e(pz_winmodels) stores the RMSE and optimal bandwidth for the optimal model within each combination of polynomial and covariates

e(pz_rep_results) stores the estimates and conventional standard errors and p-values for the optimal specification at each placebo threshold

In addition, pzms retains all of the e(class) results saved by the regress command.

References

Kettlewell N. & Siminski P. (2022). Optimal Model Selection in RDD and Related Settings Using Placebo Zones, mimeo

Authors

Nathan Kettlewell, Economics Discipline Group, University of Technology Sydney: email: Nathan.Kettlewell@uts.edu.au

Peter Siminski, Economics Discipline Group, University of Technology Sydney: email: Peter.Siminski@uts.edu.au