Correction to Conley Standard Errors

Jordan Adamson found an error in the code that Solomon Hsiang developed to compute Conley standard errors in Stata. Unfortunately, we transcribed this error when we implemented Hsiang’s code in C++ and R. These errors happen, and Hsiang clearly warns users at the top of his code.

The problem is a single misplaced parathesis in the line calcluating the weight for the Bartlett kernel when correcting for temporal auto-correlation: weight = (1:-abs(time1[t,1] :- time1))/(lag_cutoff+1) (line 430 in the original ado file, version dated 4/29/2013).

Per Newey and West (1987), the Bartlett kernel is $$K_j = 1 - \frac{|j|}{m + 1}$$

However, the line above instead computes: $$K_j = \frac{1 - |j|}{m + 1}$$

The fix is simple: the third parenthesis needs to be moved to the end of the line. Unfortunately, the fix is also consequential, as the uncorrected code can deliver negative weights and lead to standard errors that are too small when there is positive temporal auto-correlation.

Our old and new code is now posted in a public GitHub repo.


Original Code

Here’s the original Stata implementation.

clear
use "data/new_testspatial.dta"

tab year, gen(yy_)
tab FIPS, gen(FIPS_)

ols_spatial_HAC EmpClean00 HDD CDD yy_* FIPS_2-FIPS_362,
    lat(lat ) lon(lon ) t(year) p(FIPS) dist(500) lag(5) bartlett disp

This code delivers the following standard errors:

-----------------------------------------------
    Variable |   OLS      spatial    spatHAC
-------------+---------------------------------
         HDD |    0.650      0.886      0.894
         CDD |    1.493      4.068      4.388

And our original C++/R implementation:

# Loading sample data:
dt <- read.dta("data/new_testspatial.dta") %>% data.table()
setnames(dt, c("latitude", "longitude"), c("lat", "lon"))

# Loading R function to compute Conley SEs:
source("code/archived-code/deprecated-conley.R")

m <- felm(EmpClean00 ~ HDD + CDD | year + FIPS | 0 | lat + lon,
  data = dt[!is.na(EmpClean00)], keepCX = TRUE)

SE <- ConleySEs(reg = m,
    unit = "FIPS",
    time = "year",
    lat = "lat", lon = "lon",
    dist_fn = "SH", dist_cutoff = 500,
    lag_cutoff = 5,
    cores = 1,
    verbose = FALSE)

sapply(SE, function(x) diag(sqrt(x))) %>% round(3)
      OLS Spatial Spatial_HAC
HDD 0.650   0.886       0.895
CDD 1.493   4.065       4.386

This matches the standard errors from the Stata output.


Corrected Code

Jordan caught the transcribed error on line 183 of our C++ code. Per Newey and West (1987), we correct (1 - t_diff[j]) / (cutoff + 1) to (1 - t_diff[j] / (cutoff + 1)) and recompute the standard errors.

source("code/conley.R")

SE <- ConleySEs(reg = m,
    unit = "FIPS",
    time = "year",
    lat = "lat", lon = "lon",
    dist_fn = "SH", dist_cutoff = 500,
    lag_cutoff = 5,
    cores = 1,
    verbose = FALSE)

sapply(SE, function(x) diag(sqrt(x))) %>% round(3)
      OLS Spatial Spatial_HAC
HDD 0.650   0.886       0.721
CDD 1.493   4.065       3.631

As is apparent from the final column, correcting the error meaningfully changes the standard errors in the last column. Thiemo’s data is a bit unusual; in other applications with positive temporal auto-correlation, we find that the standard errors tend to increase with the corrected code.


sessionInfo()
R version 3.3.0 (2016-05-03)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.12.6 (unknown)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods
[7] base

other attached packages:
 [1] RcppArmadillo_0.7.400.2.0 Rcpp_0.12.12
 [3] geosphere_1.5-5           sp_1.2-5
 [5] lfe_2.5-1998              Matrix_1.2-7.1
 [7] ggplot2_2.2.0             foreign_0.8-67
 [9] data.table_1.9.6          dplyr_0.7.2
[11] knitr_1.14

loaded via a namespace (and not attached):
 [1] formatR_1.4       plyr_1.8.4        bindr_0.1
 [4] tools_3.3.0       digest_0.6.12     evaluate_0.10
 [7] tibble_1.3.3      gtable_0.2.0      lattice_0.20-34
[10] pkgconfig_2.0.1   rlang_0.1.1       yaml_2.1.13
[13] bindrcpp_0.2      stringr_1.2.0     rprojroot_1.1
[16] grid_3.3.0        glue_1.1.1        R6_2.2.2
[19] rmarkdown_1.2     Formula_1.2-1     magrittr_1.5
[22] backports_1.0.4   scales_0.4.1.9002 htmltools_0.3.5
[25] assertthat_0.2.0  colorspace_1.2-6  xtable_1.8-2
[28] sandwich_2.3-4    stringi_1.1.5     lazyeval_0.2.0
[31] munsell_0.4.3     chron_2.3-47      zoo_1.7-13
Darin Christensen
Darin Christensen
Associate Professor of Public Policy & Political Science

Political scientist interested in conflict and development.