---
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.
