Spatial Weight Matrices

Spatial Weight Matrices can be created from different geometries (polygons, multi polygons, or points) or raw data in Matrix format. By default, spatial weights will be row-standardized so that all rows sum to 1.

The package implements GeoInterface.jl 1.0 traits for geospatial vector data. Therefore, any geospatial data loaded with a package that implements this feature, such as Shapefile.jl or GeoDataFrames.jl, should, in principle, be compatible with this package.

Polygon contiguity

The polyneigh function creates a spatial weights object that identifies as neighbors those polygons that are physically contiguous.

using SpatialDependence
using SpatialDatasets

guerry = sdataset("Guerry")
W = polyneigh(guerry.geometry)
Spatial Weights 
Observations: 85 
Transformation: row
Minimum nunmber of neighbors: 2
Maximum nunmber of neighbors: 8
Average number of neighbors: 4.9412
Median number of neighbors: 5.0
Islands (isloated): 0
Density: 5.8131% 

By default, the queen contiguity criterion will be used for contiguity. It is possible to specify a Rook criterion by setting the parameter criterion to :Rook.

Example block output
W = polyneigh(guerry.geometry, criterion = :Rook)

When the geometry has imperfections and polygons do not touch completely, a tolerance parameter for contiguity can be set with tol.

Points distance threshold

For points geometry, a spatial weights object that identifies as neighbors those points that are below or equal to a specific threshold is computed with the dnearneigh function:

using SpatialDependence
using SpatialDatasets

boston = sdataset("Bostonhsg")
W = dnearneigh(boston.geometry, threshold = 4.0)
Spatial Weights 
Observations: 506 
Transformation: row
Minimum nunmber of neighbors: 1
Maximum nunmber of neighbors: 178
Average number of neighbors: 72.2253
Median number of neighbors: 56.0
Islands (isloated): 0
Density: 14.2738% 

The dnearneigh function can also be used with two vectors of coordinates:

W = dnearneigh(boston.x, boston.y, threshold = 4.0)
Spatial Weights 
Observations: 506 
Transformation: row
Minimum nunmber of neighbors: 1
Maximum nunmber of neighbors: 178
Average number of neighbors: 72.2253
Median number of neighbors: 56.0
Islands (isloated): 0
Density: 14.2738% 

Points K nearest neighbors

For points geometry, a spatial weights object that identifies the k-nearest neighbors is computed with the knearneigh function:

using SpatialDependence
using SpatialDatasets

boston = sdataset("Bostonhsg")
W = knearneigh(boston.geometry, k = 5)
Spatial Weights 
Observations: 506 
Transformation: row
Minimum nunmber of neighbors: 5
Maximum nunmber of neighbors: 5
Average number of neighbors: 5.0
Median number of neighbors: 5.0
Islands (isloated): 0
Density: 0.9881% 

The knearneigh function can also be used with two vectors of coordinates:

W = knearneigh(boston.x, boston.y, k = 5)
Spatial Weights 
Observations: 506 
Transformation: row
Minimum nunmber of neighbors: 5
Maximum nunmber of neighbors: 5
Average number of neighbors: 5.0
Median number of neighbors: 5.0
Islands (isloated): 0
Density: 0.9881% 

Polygon centroids

Polygon centroids and mean centers are computed with the centroid and meancenter functions.

cx, cy = centroid(guerry.geometry);
cmx, cmy = meancenter(guerry.geometry);

Polygon centroids can be used to calculate neighbors based on distance thresholds or k nearest neighbors.

knearneigh(cx, cy, k = 5)
Spatial Weights 
Observations: 85 
Transformation: row
Minimum nunmber of neighbors: 5
Maximum nunmber of neighbors: 5
Average number of neighbors: 5.0
Median number of neighbors: 5.0
Islands (isloated): 0
Density: 5.8824% 

Spatial Weights from a Matrix

It is possible to create a spatial weights object by supplying a square Matrix. All values that are different from 0 will be neighbors.

W = SpatialWeights([0 1 0; 1 0 1; 0 1 0])
Spatial Weights 
Observations: 3 
Transformation: row
Minimum nunmber of neighbors: 1
Maximum nunmber of neighbors: 2
Average number of neighbors: 1.3333
Median number of neighbors: 1.0
Islands (isloated): 0
Density: 44.4444% 

By default, the spatial weights will be row-standardized. However, it is possible to keep the original values in the Matrix as weighs by setting the standardize optional parameter to false.

W = SpatialWeights([0 1 0; 1 0 1; 0 1 0], standardize = false)

Spatial Weights transformation

By default, Spatial weight objects are row-standardized, with rows summing 1. It is possible to specify a different transformation with the wtransform! and wtransform functions. wtransform! applies an in-place transformation to the spatial weights object. In contrast,wtransform returns a transformed copy of the spatial weights object.

Available transoformations are:

CodeTransformation
:binaryBinary coding
:rowRow standardization
wtransform!(W, :binary)
Wbin = wtransform(W, :binary)
Spatial Weights 
Observations: 85 
Transformation: binary
Minimum nunmber of neighbors: 2
Maximum nunmber of neighbors: 8
Average number of neighbors: 4.9412
Median number of neighbors: 5.0
Islands (isloated): 0
Density: 5.8131% 

Spatial Weights information

There is a set of functions to obtain information about spatial weights objects.

The function nobs returns the number of observations in the spatial weights object.

nobs(W)
85

The number of neighbors of each observation is returned with the cardinalities function:

cardinalities(W)
85-element Vector{Int64}:
 4
 6
 6
 4
 3
 7
 3
 3
 5
 5
 ⋮
 5
 6
 3
 6
 4
 6
 6
 6
 5

A vector of neighbors for particular observations is obtained with the neighbors function:

neighbors(W, 1)
4-element Vector{Int64}:
 36
 37
 67
 69

And a vector of weights with the weights function:

weights(W, 1)
4-element Vector{Float64}:
 0.25
 0.25
 0.25
 0.25

The number of islands - observatiosn with no neighbors - is obtained with the nislands function, and the vector of islands with the islands function.

nislands(W)
0
islands(W)
Int64[]

Spatial weights objects implement the following methods to obtain descriptive statistics of the number of neighbors: minimum, maximum, mean, median.

Connectivity Histogram

The plot function with a spatial weights object plots a connectivity histogram for the number of neighbors.

plot(W)
Example block output

Convert to other objects

Spatial weights objects can be converted to a Matrix using the Matrix constructor:

Matrix(W)
85×85 Matrix{Float64}:
 0.0  0.0       0.0  0.0       0.0   …  0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.25     0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.333333  0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0   …  0.0  0.0       0.0       0.0  0.0
 0.0  0.333333  0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.2
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0
 ⋮                                   ⋱  ⋮                             
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.333333  0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.166667  0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0   …  0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.166667  0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.166667  0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0
 0.0  0.0       0.0  0.0       0.0      0.0  0.0       0.0       0.0  0.0

and to a sparse matrix with the sparse function:

sparse(W)
85×85 SparseArrays.SparseMatrixCSC{Float64, Int64} with 420 stored entries:
⎡⠀⠀⡀⠂⠀⠀⠀⠠⠀⠠⠀⡀⠀⠀⠀⠀⠈⠁⠠⠀⠀⠀⠐⠀⠀⠀⠔⠂⠄⠀⠀⠁⠅⠀⠂⠐⢀⡀⠀⠀⎤
⎢⠠⠈⠀⠀⡀⠀⠀⠀⠀⠀⠀⠃⠐⡀⠀⠀⠘⠀⠐⠂⠀⠂⠠⠀⠠⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠂⠀⠀⎥
⎢⠀⠀⠀⠈⠀⠀⠂⠀⠈⠀⠀⢀⠰⠁⠘⠀⠀⠀⠀⠀⠂⠂⡈⠁⠀⠀⠀⢀⠀⠈⠀⠀⠀⠀⠁⠘⠢⠄⠀⠈⎥
⎢⠀⡀⠀⠀⠈⠀⠠⠂⠁⢀⠆⠀⠀⠀⠄⢀⠀⠀⡀⢁⠁⠁⠀⠀⠀⠀⡀⠀⠁⠀⠀⠀⠀⠀⠀⠆⠀⠠⠒⠀⎥
⎢⠀⡀⠀⠀⠂⠀⠁⢀⡀⠈⠁⠀⠄⠀⠀⢄⠀⠂⠀⠀⠁⠀⠀⠂⠀⠄⠂⠀⡁⠀⠀⠐⠂⠀⠀⠀⠀⠀⢈⠐⎥
⎢⠀⠠⠤⠀⠀⢀⠈⠁⠁⠀⠀⠀⡀⠀⠁⠀⠠⠂⠀⠀⠉⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠐⠀⢀⢀⠀⠀⠄⠈⠀⎥
⎢⠀⠀⠐⠠⠔⠂⠀⠀⠀⠁⠀⠈⠀⡠⠐⠀⠀⢀⠁⠈⢀⠂⠀⠀⠀⠁⠀⠈⢀⡄⠀⠀⠈⠀⠈⠠⡄⠂⠀⠀⎥
⎢⠀⠀⠀⠀⠒⠀⠀⢁⠀⢄⠁⠀⠐⠀⠀⠀⡀⠈⡀⠠⠈⠠⠄⠠⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠀⣀⠀⎥
⎢⠆⠀⠒⠀⠀⠀⠀⠀⠠⠀⠠⠂⠀⢀⡀⠈⠀⠀⠑⠀⢀⠈⠀⠀⠀⠀⠀⠀⢀⠀⠀⠢⠌⠀⠀⠀⠀⠀⠁⠀⎥
⎢⠀⠂⠰⠀⠀⠀⠄⢈⠀⠀⠀⠀⡁⠀⠀⡈⠑⠀⡠⠊⠀⢄⠀⠀⠀⡀⡀⠀⠆⠀⠀⠂⠊⠀⣀⠀⠀⢀⠀⢀⎥
⎢⠀⠀⠠⠀⠨⠀⠅⠀⠁⠀⠃⠀⠠⠐⠂⡀⡀⠐⠀⢄⠊⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⡀⠃⢀⡀⠀⎥
⎢⠐⠀⠀⠂⠆⠈⠀⠀⠠⠀⠀⠀⠀⠀⠀⡁⠀⠀⠀⠀⠀⢀⡠⠊⠰⠀⠀⢈⠀⠀⠀⠠⢀⠀⠂⠀⠀⠀⠀⠄⎥
⎢⠀⠀⠀⠂⠀⠀⠀⠀⠀⠄⠀⠀⠄⠀⠀⠄⠀⠀⠀⠠⠀⠀⠐⠂⡊⠈⠀⠀⠀⠀⡁⠀⠀⠀⠀⠀⠀⠀⠀⠃⎥
⎢⠰⠁⠀⠀⠀⢀⠀⠈⠈⠀⠀⢠⡀⠀⠀⠀⠀⠀⠀⠈⠀⠀⡀⢀⠀⠀⢀⠐⠀⠀⠀⠀⢁⠠⠤⢰⠀⠀⠀⠈⎥
⎢⠀⠁⠀⢀⡀⠀⠁⠀⠁⠈⠀⠀⠀⠴⠀⠀⠀⠐⠈⠁⠀⠀⠀⠀⠀⠀⠀⠀⠠⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⎥
⎢⠄⠀⠀⠀⠀⠀⠀⠀⢀⠀⢀⠀⠀⠀⠀⠀⠠⡀⠠⠀⠀⠀⠀⡀⠁⠈⠀⠀⠀⠀⠊⠀⠄⠀⠀⠀⠀⠀⠀⡃⎥
⎢⠁⠁⠀⠀⠀⠀⠀⠀⠈⠀⠀⢀⠂⠀⠀⠀⠂⠁⠊⠀⠀⠐⠀⠐⠀⠀⠁⡐⠀⠀⠀⠁⠀⠀⠤⢀⠀⠀⠀⠀⎥
⎢⢈⠀⠀⠀⣁⠀⠠⠄⠀⠀⠀⠐⠂⡀⢀⠀⠀⠀⠀⠘⠀⠠⠈⠀⠀⠀⢀⣃⠀⠀⠀⠀⠀⢃⠊⠀⡀⠠⠄⠈⎥
⎢⠀⠰⠠⠀⠈⠆⠀⡀⠀⠀⠀⠄⠠⠉⠀⠀⠀⠀⠀⢀⠉⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡈⠠⠂⠀⠀⎥
⎣⠀⠀⠀⠀⡀⠀⠘⠀⢂⠐⠂⠀⠀⠀⠀⠘⠁⠀⠀⢀⠀⠈⠀⠄⠤⠀⡀⠀⠀⠀⠤⠠⠀⠀⡀⠁⠀⠀⠊⠀⎦