---
title: "Getting started with slxr"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting started with slxr}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
```

## The Spatial-X model

The Spatial-X (SLX) model has the form

$$
y = X\beta + WX\theta + \varepsilon,
$$

where `W` is a spatial weights matrix and `WX` adds spatially-lagged
versions of selected regressors. Wimpy, Whitten, and Williams (2021)
argue that the SLX specification more faithfully reflects typical
political science theories than the more common SAR model, and is
much easier to estimate and interpret: it is plain OLS on an augmented
design matrix.

`slxr` exists because the mechanics of building `W`, multiplying it by
the right columns of `X`, and reporting direct/indirect/total effects
cleanly is more friction than applied researchers should have to
endure.

## The example dataset

The package ships with `defense_burden`, a 1995 cross-section of 179
countries drawn from the replication archive of Wimpy, Whitten, and
Williams (2021). The data include change in military expenditures
(the outcome), lagged covariates, and three row-standardized spatial
weights matrices encoding different channels of international
connectivity.

```{r load}
library(slxr)
data(defense_burden)

names(defense_burden)
dim(defense_burden$data)
dim(defense_burden$W_contig)
```

`defense_burden$data` is a tibble with country-level observations.
`defense_burden$W_contig`, `$W_alliance`, and `$W_defense` are sparse
weights matrices connecting those countries through geographic
contiguity, alliance ties, and mutual defense pacts, respectively.

## Fitting an SLX model with a single W

The simplest case: one weights matrix, one lagged variable. We lag
only `total_wars_tm1` through contiguity, so the indirect effect
captures the spillover from interstate wars in neighboring countries.

```{r single-w}
W_contig <- slx_weights(style = "custom",
                        matrix = defense_burden$W_contig,
                        row_standardize = FALSE)

fit <- slx(ch_milex ~ milex_tm1 + log_pop_tm1 + civilwar_tm1 +
                      total_wars_tm1 + alliance_us +
                      ch_milex_us + ch_milex_ussr,
           data = defense_burden$data,
           W = W_contig,
           lag = "total_wars_tm1")

summary(fit)
```

The `W.total_wars_tm1` row is the spatial spillover. To get a clean
direct/indirect/total decomposition:

```{r single-w-effects}
slx_effects(fit)
```

For SLX these effects are a simple function of OLS coefficients and
their variance-covariance matrix - no matrix inversion, no simulation.

## Variable-specific weights matrices

The defining feature of Wimpy, Whitten, and Williams (2021) is that
different covariates can spill over through different `W` matrices.
Civil wars spread through geography; alliance ties produce joint
responses to interstate conflict; defense-pact partners coordinate
military spending. All three mechanisms can sit in a single model.

```{r multi-w}
W_alliance <- slx_weights(style = "custom",
                          matrix = defense_burden$W_alliance,
                          row_standardize = FALSE)
W_defense  <- slx_weights(style = "custom",
                          matrix = defense_burden$W_defense,
                          row_standardize = FALSE)

fit_multi <- slx(
  ch_milex ~ milex_tm1 + log_pop_tm1 + civilwar_tm1 +
             total_wars_tm1 + alliance_us +
             ch_milex_us + ch_milex_ussr,
  data = defense_burden$data,
  spatial = list(
    civilwar_tm1   = W_contig,
    total_wars_tm1 = list(contig = W_contig, alliance = W_alliance),
    milex_tm1      = list(contig = W_contig, defense  = W_defense)
  )
)

slx_effects(fit_multi)
```

Here `total_wars_tm1` and `milex_tm1` each produce two indirect
effects - one through each spatial channel - so the decomposition
separates spillovers from geographically-contiguous neighbors from
those transmitted through alliances or defense pacts.

## Visualization

```{r plot, fig.width = 7, fig.height = 4}
library(ggplot2)
slx_plot_effects(fit_multi, types = c("indirect", "total"))
```

The plot facets automatically by weights matrix name when a variable
is lagged through multiple `W` channels, so the per-channel spillover
patterns are visible side-by-side.

## broom and modelsummary integration

```{r broom, eval = FALSE}
tidy(fit_multi)
glance(fit_multi)

modelsummary::modelsummary(
  list("Contiguity only" = fit, "Multi-W" = fit_multi),
  statistic = "conf.int"
)
```

## Caveats

This vignette uses a single cross-section from 1995 because the
current release of `slxr` does not yet support block-diagonal panel
`W` matrices. A full-panel replication of Wimpy, Whitten, and
Williams (2021) Table 3, Model 3 is planned for v0.2 alongside
TSLS support.

## References

Wimpy, C., Whitten, G. D., & Williams, L. K. (2021). X Marks the
Spot: Unlocking the Treasure of Spatial-X Models. *Journal of
Politics*, 83(2), 722-739.
