Spatial Diagnostics

Moran's I, Geary's c, LISA and the Anselin LM specification battery.

SpatialEconometrics.SpatialDiagnostics.GearyCResult — Type
GearyCResult

Geary's c with its reference moments, returned by geary_c.

Fields

  • C_stat: the statistic. Its null expectation is 1; below 1 indicates positive spatial autocorrelation and above 1 negative — the opposite direction to Moran's I.
  • E_C: expectation under the null, 1.
  • Var_C: variance under the null.
  • z_stat: (C_stat - E_C) / sqrt(Var_C), so a negative z_stat means positive autocorrelation.
  • p_value: two-sided.
source
SpatialEconometrics.SpatialDiagnostics.LISAResult — Type
LISAResult

Local indicators of spatial association, returned by moran_local. All four vectors are length N and aligned with the units of y.

Fields

  • local_I: the local Moran statistic per unit. These sum to the global statistic up to a scale factor.
  • pseudo_p: conditional-permutation p-value per unit.
  • cluster_type: one of :HH, :LL, :HL, :LH or :ns — note these are Symbols, not strings. :HH and :LL mark clusters of high and of low values; :HL and :LH mark spatial outliers; :ns marks units with pseudo_p > 0.05.
  • z_scores: standardized y, the basis of the H/L classification.
Warning

Each unit is tested separately, so with many units some will be flagged by chance. Treat the map as exploratory unless the p-values are adjusted for multiplicity.

source
SpatialEconometrics.SpatialDiagnostics.LMTestResult — Type
LMTestResult

One Lagrange-multiplier specification test, returned by lm_test_lag and its siblings.

Fields

  • stat: the test statistic, asymptotically chi-squared with 1 degree of freedom under the null of no spatial dependence.
  • p_value: upper-tail probability.
  • test_name: which test produced it.
source
SpatialEconometrics.SpatialDiagnostics.MoranResult — Type
MoranResult

Global Moran's I with its reference moments, returned by moran_global.

Fields

  • I_stat: the statistic. Positive means like values cluster together, negative means neighbours tend to differ.
  • E_I: expectation under no spatial autocorrelation, -1/(N-1) — note that it is slightly negative, not zero.
  • Var_I: variance under the same null.
  • z_stat: (I_stat - E_I) / sqrt(Var_I).
  • p_value: two-sided.
  • method: :asymptotic or :permutation, recording how p_value was obtained.
source
SpatialEconometrics.SpatialDiagnostics.geary_c — Function
geary_c(y, W)

Geary's c, a test for spatial autocorrelation built on differences between neighbours.

\[c = ((N-1) / (2 S_0)) * sum_ij w_ij (y_i - y_j)^2 / sum_i (y_i - ybar)^2\]

Where Moran's I is a cross-product statistic and so responds to the global pattern, Geary's c sums squared differences across linked pairs and is therefore more sensitive to local, short-range variation. Using both is informative when they disagree.

Returns

A GearyCResult.

Note

The scale runs the other way from Moran's I: the null expectation is 1, values below 1 indicate positive autocorrelation, and z_stat is correspondingly negative when values cluster.

Examples

g = geary_c(y, W)
g.C_stat < 1      # positive autocorrelation

See also moran_global.

References

Anselin, L. (1988). Spatial Econometrics: Methods and Models. Kluwer.

source
SpatialEconometrics.SpatialDiagnostics.lm_test_error — Function
lm_test_error(y, X, W)

Anselin's LM test for spatially autocorrelated errors.

Tests H0: lambda = 0 in y = X*beta + u, u = lambda*W*u + e, from OLS residuals. Chi-squared with 1 degree of freedom.

Like lm_test_lag it is not robust to the other form of dependence; see lm_test_robust_error and lm_tests. X must include an intercept column; none is added for you.

Returns

An LMTestResult.

References

Anselin, L. (1988). Spatial Econometrics: Methods and Models. Kluwer.

source
SpatialEconometrics.SpatialDiagnostics.lm_test_lag — Function
lm_test_lag(y, X, W)

Anselin's LM test for an omitted spatial lag of the dependent variable.

Fitted by OLS under the null of no spatial dependence, this tests H0: rho = 0 in y = rho*W*y + X*beta + e against the alternative that a lag belongs in the model. The statistic is chi-squared with 1 degree of freedom.

It is not robust: a spatial error process also inflates it, so a rejection on its own does not distinguish lag from error dependence. Use lm_test_robust_lag, or lm_tests for the whole battery. X must include an intercept column; none is added for you.

Returns

An LMTestResult.

References

Anselin, L. (1988). Spatial Econometrics: Methods and Models. Kluwer.

source
SpatialEconometrics.SpatialDiagnostics.lm_test_robust_error — Function
lm_test_robust_error(y, X, W)

LM test for spatially autocorrelated errors, robust to the presence of an omitted spatial lag.

The counterpart to lm_test_robust_lag; together they are what separates an error process from a lag process when both plain tests reject. X must include an intercept column; none is added for you.

Returns

An LMTestResult.

References

Anselin, L., Bera, A., Florax, R. & Yoon, M. (1996). Regional Science and Urban Economics, 26(1).

source
SpatialEconometrics.SpatialDiagnostics.lm_test_robust_lag — Function
lm_test_robust_lag(y, X, W)

LM test for an omitted spatial lag, robust to the presence of spatial error dependence.

This is the test to read when both plain statistics reject. It corrects lm_test_lag for local misspecification of the error process, so a rejection points at the lag specifically rather than at spatial dependence in general. X must include an intercept column; none is added for you.

Returns

An LMTestResult.

See also lm_tests, lm_test_robust_error.

References

Anselin, L., Bera, A., Florax, R. & Yoon, M. (1996). Simple diagnostic tests for spatial dependence. Regional Science and Urban Economics, 26(1).

source
SpatialEconometrics.SpatialDiagnostics.lm_tests — Function
lm_tests(y, X, W) -> NamedTuple

Run the full Anselin specification-search battery and return all four tests as (; lag, error, robust_lag, robust_error).

This is the usual way to decide which spatial model to fit. The standard reading:

Plain testsRobust testsIndication
neither rejects—OLS is adequate
only lag rejects—fit SAR
only error rejects—fit a spatial error model
both rejectrobust_lag onlyfit SAR
both rejectrobust_error onlyfit a spatial error model
both rejectboth rejectconsider SDM or SARAR

Each element is an LMTestResult.

Examples

t = lm_tests(y, hcat(ones(N), X), W)      # X needs the intercept column
t.lag.p_value, t.robust_lag.p_value

# fit_spatial does add its own intercept, so pass the bare X there
m = t.robust_lag.p_value < t.robust_error.p_value ?
        fit_spatial(SAR(), W, X, y) : fit_spatial_error(W, X, y)
Warning

X must already include an intercept column — the OLS step is a bare qr(X) \ y and adds nothing. Pass hcat(ones(N), X), or the residuals are taken around zero and every statistic is wrong.

References

Anselin, L., Bera, A., Florax, R. & Yoon, M. (1996). Regional Science and Urban Economics, 26(1).

source
SpatialEconometrics.SpatialDiagnostics.moran_global — Function
moran_global(y, W; inference = :asymptotic, n_perm = 999, rng = Random.default_rng())

Global Moran's I, the standard test for spatial autocorrelation in y.

\[I = (N/S_0) * (z' W z) / (z' z)\]

where z is y in deviations from its mean and S_0 is the sum of all weights. When W is row-standardized S_0 = N and I reduces to the slope of Wz on z, which is why it can be read off a Moran scatter plot (plot_moran_scatter).

Keywords

  • inference: :asymptotic uses the normal approximation with the exact finite-sample variance, correcting for the kurtosis of y. :permutation instead randomly reassigns y across locations n_perm times and reports the rank of the observed statistic, which makes no distributional assumption and is the safer choice for small N or heavy-tailed y.
  • n_perm, rng: used only when inference = :permutation.

Returns

A MoranResult.

Note

The null expectation is -1/(N-1), not 0, so compare I_stat against E_I rather than against zero — the difference matters in small samples.

Examples

W = make_rook_weights(10)
moran_global(y, W)
moran_global(y, W; inference = :permutation, n_perm = 9999)

m = fit_spatial(SAR(), W, X, y)
moran_global(residuals(m), W)      # did the model absorb the dependence?

See also moran_local, geary_c, lm_tests.

References

Anselin, L. (1988). Spatial Econometrics: Methods and Models. Kluwer.

source
SpatialEconometrics.SpatialDiagnostics.moran_local — Function
moran_local(y, W; n_perm = 999, rng = Random.default_rng())

Local Moran's I per unit, with conditional-permutation inference and LISA cluster classification.

Where moran_global asks whether there is clustering anywhere, this asks where it is. Inference is conditional: unit i's own value is held fixed while the remaining N-1 values are permuted among the other locations, which is the appropriate null for a local statistic.

Each unit is then labelled by the sign of its own standardized value and of its spatial lag: :HH and :LL for clusters, :HL and :LH for spatial outliers, and :ns where pseudo_p > 0.05.

Returns

A LISAResult.

Warning

These are N simultaneous tests, so some units will be significant by chance alone; the 0.05 cut used for :ns is unadjusted. Read the classification as exploratory.

Examples

lisa = moran_local(y, W; n_perm = 9999)
count(==(:HH), lisa.cluster_type)
plot_local_moran(lisa, coords)          # needs a Makie backend

References

Anselin, L. (1995). Local indicators of spatial association — LISA. Geographical Analysis, 27(2).

source