--- title: "Stop-crime slopes and cross-sectional dependence" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Stop-crime slopes and cross-sectional dependence} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") library(streetlamp) ``` ## Estimate the count mean on an explicit scale A recorded count and a conditional mean are different quantities. The fixed-effects method defaults to Poisson pseudo-likelihood, modelling expected recorded counts, with clustered covariance. The stop covariate is `log(1 + stops)`. Its coefficient is a log-mean slope per unit of that covariate; at intensity S, the conventional stops elasticity is the slope multiplied by `S / (1 + S)`. ```{r count-mean} sim <- lamp_simulate(n_areas = 40, n_months = 36, design = "continuous", effect = -0.2, base_rate = 30, seed = 5) fit <- lamp_elasticity(sim, "affected_crime", lags = 0:3, method = "fe") fit lamp_effect_summary(fit) ``` The lag sum describes a persistent shift in log-one-plus stop intensity. Calendar months define the lags: an absent month cannot turn a two-month-old observation into last month's value. The fitted sample and exclusions are reported. Poisson pseudo-likelihood includes zeros and uses robust clustered covariance rather than imposing Poisson variance for inference. It still requires a correctly specified mean and suitable exogeneity. ## Common correlated effects have a different response scale The CCE implementations currently model `log(1 + observed crime)`. That is not `log(expected crime)`, especially with sparse counts. For a comparison between the three implementations on that response scale, explicitly select legacy OLS for the FE row: ```{r common-factors} legacy_fe <- lamp_elasticity(sim, "crime_total", lags = 0:1, family = "ols_log") pooled <- lamp_elasticity(sim, "crime_total", lags = 0:1, method = "cce_pooled") mg <- lamp_elasticity(sim, "crime_total", lags = 0:1, method = "cce_mg") rbind(fe = lamp_effect_summary(legacy_fe), cce_pooled = lamp_effect_summary(pooled), cce_mg = lamp_effect_summary(mg)) ``` CCE uses cross-sectional averages to proxy common factors. Mean-group inference averages area slopes and uses their cross-area dispersion. Force clustering for that method is not implemented and is rejected. The auxiliary Pesaran CD statistic uses an OLS regression of log-one-plus outcomes with area effects only. A large value describes shared movements. It does not establish that the clustered intervals from the primary count model are invalid, or that adding common-factor proxies identifies a cause. ## Reverse allocation remains an identification question ```{r allocation} allocation <- lamp_allocation(sim, crime_lags = 1:3) allocation$diagnostics$interpretation ``` Police deployment can respond to recent or anticipated crime. A detected allocation response must be considered when interpreting the stop-crime association. A non-significant response does not establish exogeneity or rule out reverse allocation through other channels. Neither coefficient sign supplies an intervention assignment mechanism. ## Converting the estimate requires further assumptions ```{r conversion} lamp_crimes_prevented(fit, sim) ``` This is a local arithmetic approximation at fitted-sample means. Because the covariate is log-one-plus stops, its denominator is mean stops plus one. A count-mean slope uses mean crime in the numerator. Legacy OLS requires an approximation on mean crime plus one and cannot be treated as an expected count effect without further retransformation assumptions. The output retains the assumption chain and does not certify prevention. See `vignette("research-validation", package = "streetlamp")` for heterogeneous effects, simulation truth, complete robustness grids, conditional trend sensitivity and the limits of the London empirical case.