Skip to contents

R 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 is log(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_spatial from 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