
Replication of Laniyonu (2018) — Coffee Shops and Street Stops
Source:R/laniyonu_gentrification_policing.R
morie_laniyonu_gentrification_policing.RdR port of morie.laniyonu.gentrification_policing. Estimates
the direct, indirect (spatial spillover), and total effect of
gentrification on NYPD stop-and-frisk rates at the census-tract x
year level via a Spatial Durbin Model (SDM) decomposition.
Usage
morie_laniyonu_gentrification_policing(
df,
year_col = "year",
tract_id_col = "tract_id",
stops_col = "stops",
population_col = "population",
crime_col = "felony_count",
demand_col = "calls_311_omp",
baseline_income_col = "median_inc_2000",
baseline_rent_col = "median_rent_2000",
growth_college_col = NULL,
growth_rent_col = NULL,
follow_income_col = "median_inc_2014",
follow_rent_col = "median_rent_2014",
baseline_college_col = "pct_ba_2000",
follow_college_col = "pct_ba_2014",
additional_controls = NULL,
weight_matrix = NULL,
weight_matrix_kind = c("queen", "knn"),
fitted_rho = NULL,
fitted_beta_direct = NULL,
fitted_beta_spatial = NULL,
years = NULL,
log_outcome = TRUE
)Arguments
- df
Tract-year panel. One row per tract per year.
- year_col, tract_id_col, stops_col, population_col, crime_col, demand_col
Column names; defaults match the morie toy capsule schema.
- baseline_income_col, baseline_rent_col
Baseline-period income and rent (2000 in the paper).
- growth_college_col, growth_rent_col
Growth columns. If
NULL, computed from follow-minus-baseline.- follow_income_col, follow_rent_col, baseline_college_col, follow_college_col
Used when growth columns are not pre-computed.
- additional_controls
Extra tract-year controls (pct_black, etc.).
- weight_matrix
Pre-computed (N, N) row-standardised spatial weights. Required when
fitted_*mode is in use.- weight_matrix_kind
Provenance label only.
- fitted_rho, fitted_beta_direct, fitted_beta_spatial
Pre-fitted SDM outputs. Pass these to bypass lite-mode.
- years
Subset of years to analyse.
- log_outcome
If
TRUE(default), outcome islog(stops / population).
Value
A list of class morie_laniyonu_gp_result, one
per year analysed.
A list of morie_laniyonu_gp_result, one per
year analysed.
Details
The paper's headline finding: gentrification has roughly zero direct effect on stops/capita inside the gentrifying tract, but a +51\ stops/capita in neighbouring tracts.
Two modes are supported:
Pre-fitted mode (preferred): pass
fitted_rho,fitted_beta_direct,fitted_beta_spatialfrom your own SDM fit (e.g.\ spatialreg::lagsarlm with Durbin terms). This wrapper handles the diagnostic ladder + Kelejian-Prucha spillover decomposition.Lite mode (fall-back): OLS + Moran's I on residuals, decomposition with rho=0. Useful for sanity-checks only.
References
Laniyonu, A. (2018). Coffee shops and street stops: Policing practices in gentrifying neighborhoods. Urban Affairs Review, 54(5), 898-930.
LeSage, J. P., & Pace, R. K. (2009). Introduction to Spatial Econometrics. CRC Press.
Examples
set.seed(1)
df <- expand.grid(tract_id = sprintf("T%02d", 1:40), year = 2010:2012,
stringsAsFactors = FALSE)
df$median_inc_2000 <- runif(nrow(df), 3e4, 7e4)
df$median_inc_2014 <- df$median_inc_2000 * 1.2
df$median_rent_2000 <- runif(nrow(df), 700, 1500)
df$median_rent_2014 <- df$median_rent_2000 * 1.2
df$pct_ba_2000 <- runif(nrow(df), 0.05, 0.45)
df$pct_ba_2014 <- pmin(df$pct_ba_2000 * 1.3, 0.95)
df$population <- sample(800:5000, nrow(df), TRUE)
df$stops <- rpois(nrow(df), 30); df$felony_count <- rpois(nrow(df), 10)
df$calls_311_omp <- rpois(nrow(df), 40); df$pct_black <- runif(nrow(df), 0.05, 0.7)
res <- suppressWarnings(morie_laniyonu_gentrification_policing(df = df, log_outcome = TRUE))
res[[1]]$rho
#> [1] 0