Description
Dear Roger,
I just went through your teaching materials of ECS530. Thanks a lot for this valuable resource, it is really incredibly helpful!
However, I was a bit confused by seeing the indirect impacts after running a Durbin error model in ECS530_h19/ECS530_VII.Rmd, line 118. If I'm not confusing something here, the impacts()
function after the Durbin error and the SLX seems to take up the wrong lagged coefficients from the model if a lagged intercept is included. See the example (taken from your materials) below:
library(spatialreg)
library(spdep)
library(sf)
nc <- st_read(system.file("shapes/sids.shp", package="spData")[1], quiet=TRUE)
st_crs(nc) <- "+proj=longlat +datum=NAD27"
row.names(nc) <- as.character(nc$FIPSNO)
nc$ft.SID74 <- sqrt(1000)*(sqrt(nc$SID74/nc$BIR74) + sqrt((nc$SID74+1)/nc$BIR74))
nc$ft.NWBIR74 <- sqrt(1000)*(sqrt(nc$NWBIR74/nc$BIR74) + sqrt((nc$NWBIR74+1)/nc$BIR74))
gal_file <- system.file("weights/ncCR85.gal", package="spData")[1]
ncCR85 <- read.gal(gal_file, region.id=nc$FIPSNO)
closeAllConnections()
nc_lw <- nb2listw(ncCR85, style="B")
nc_lw_w <- nb2listw(ncCR85, style="W") # row-standardized to test without intercept
# SDEM with unstandardized W and intercept in lagX
m1b <- spatialreg::errorsarlm(ft.SID74 ~ ft.NWBIR74, weights=BIR74, data=nc, listw=nc_lw, Durbin=TRUE)
summary(m1b)
summary(spatialreg::impacts(m1b))
# The indirect impact does not equal the lagged coef of ft.NWBIR74
all.equal(spatialreg::impacts(m1b)[[1]]$indirect, m1b$coefficients["lag.ft.NWBIR74"],
tolerance = 1e-5, check.attributes = FALSE)
# it equals the lagged intercept
all.equal(spatialreg::impacts(m1b)[[1]]$indirect, m1b$coefficients["lag.(Intercept)"],
tolerance = 1e-5, check.attributes = FALSE)
# Similarly, with more than one covariate, it starts with the intercept, and omits the last lag coefficient
m1c <- spatialreg::errorsarlm(ft.SID74 ~ ft.NWBIR74 + east, weights=BIR74, data=nc, listw=nc_lw, Durbin=TRUE)
summary(m1c)
summary(spatialreg::impacts(m1c))
# Indirect impact for "east" equals the lagged coefficient for "ft.NWBIR74"
all.equal(spatialreg::impacts(m1c)[[1]]$indirect["east"], m1c$coefficients["lag.ft.NWBIR74"],
tolerance = 1e-5, check.attributes = FALSE)
# Without intercept (row standardized W), everything works as expected
m1c <- spatialreg::errorsarlm(ft.SID74 ~ ft.NWBIR74 + east, weights=BIR74, data=nc, listw=nc_lw_w, Durbin=TRUE)
summary(m1c)
summary(spatialreg::impacts(m1c))
### Same problem occurs in impacts(lmSLX()) with lagged intercept
m2 <- spatialreg::lmSLX(ft.SID74 ~ ft.NWBIR74 + east, weights=BIR74, data=nc, listw=nc_lw, Durbin=TRUE)
summary(m2)
summary(spatialreg::impacts(m2))
# but everything works as expected without intercept
m2b <- spatialreg::lmSLX(ft.SID74 ~ ft.NWBIR74 + east, weights=BIR74, data=nc, listw=nc_lw_w, Durbin=TRUE)
summary(m2b)
summary(spatialreg::impacts(m2b))
To me, this looks like the lagged intercept is not taken into account when extracting the lagged coefficients for the impacts in SDEM and SLX (I did not test any other models so far)?
I'm happy to look into the code if you agree that there's something going wrong here.
Best wishes,
Tobias