You are on page 1of 35

Autokorelasi Spasial

Statistika Spasial | Praktikum ke-4
Autokorelasi temporal
d <- sample(100, 10)
a <- d[-length(d)]
b <- d[-1]
plot(a, b, xlab='t', ylab='t-1')
cor(a, b)

d <- sort(d)
a <- d[-length(d)]
b <- d[-1]
plot(a, b, xlab='t', ylab='t-1')
Contoh Data Spasial
p <- shapefile(system.file("external/lux.shp", package="raster"))
p <- p[p$NAME_1=="Diekirch", ]
p$value <- c(10, 6, 4, 11, 6)
plot(p, col=2:7)
xy <- coordinates(p)
points(xy, cex=6, pch=20, col='white')
text(p, 'ID_2', cex=1.5)
Steps in determining the extent of spatial
autocorrelation in your data :

1. Choose a neighborhood criterion

• Which areas are linked?
2. Assign weights to the areas that are linked
• Create a spatial weights matrix
3. Run statistical test to examine spatial autocorrelation
Step 1:
Choose a neighborhood criterion
Spatial weights matrices
• Neighborhoods can be defined in a number of ways
• Contiguity (common boundary)
• What is a “shared” boundary?
• Distance (distance band, K-nearest neighbors)
• How many “neighbors” to include, what distance do we use?
• General weights (social distance, distance decay)
Contiguity based neighbors
• Areas sharing any boundary point (QUEEN) are taken as neighbors, using the poly2nb function,
which accepts a SpatialPolygonsDataFrame
> library(spdep)
> w<-poly2nb(p)

• If contiguity is defined as areas sharing more than one boundary point (ROOK), the queen= argument
is set to FALSE
> w.rook<-poly2nb(p, queen=FALSE)

> coords<-coordinates(p)
> plot(p)
> plot(w, coords, add=T)
Queen contiguity Rook contiguity
Distance based neighbors
k nearest neighbors
• Can also choose the k nearest points as neighbors

> coords<-coordinates(p)
> IDs<-row.names(as(p, "data.frame"))

> p_kn1<-knn2nb(knearneigh(coords, k=1), row.names=IDs)

> p_kn2<-knn2nb(knearneigh(coords, k=2), row.names=IDs)
> p_kn4<-knn2nb(knearneigh(coords, k=4), row.names=IDs)
> plot(p)
> plot(p_kn2, coords, add=T)
k=1 k=2 k=4
Distance based neighbors : Specified distance
• Can also assign neighbors based on a specified distance

> dist<-unlist(nbdists(p_kn1, coords))

> summary(dist)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.07316 0.07316 0.14159 0.11832 0.14159 0.16213
> max_k1<-max(dist)

> p_kd1<-dnearneigh(coords, d1=0, d2=0.75*max_k1, row.names=IDs)

> p_kd2<-dnearneigh(coords, d1=0, d2=1*max_k1, row.names=IDs)
> p_kd3<-dnearneigh(coords, d1=0, d2=1.5*max_k1, row.names=IDs)

OR by raw distance dist=1.5*max_k1

> p_ran1<-dnearneigh(coords, d1=0, d2=0.16123, row.names=IDs)
Distance=0.75*max_k1 Distance=1*max_k1 Distance=1.5*max_k1
Step 2:
Assign weights to the areas that are linked
Creating spatial weights matrices using neighborhood lists
Spatial weights matrices
• Once our list of neighbors has been created, we assign spatial weights
to each relationship
• Can be binary or variable

• Even when the values are binary 0/1, the issue of what to do with no-
neighbor observations arises

• Binary weighting will, for a target feature, assign a value of 1 to

neighboring features and 0 to all other features
• Used with fixed distance, k nearest neighbors, and contiguity
Row-standardized weights matrix
> p_nbq_w<- nb2listw(w) • Row standardization is used to create
proportional weights in cases where
> p_nbq_w
features have an unequal number of
• Divide each neighbor weight for a
feature by the sum of all neighbor
• Obs i has 3 neighbors, each has a weight
of 1/3
• Obs j has 2 neighbors, each has a weight
of 1/2

• Use is you want comparable spatial

parameters across different data sets
with different connectivity structures
Binary weights
> w_nbq_wb<-nb2listw(w, style="B") • Row-standardised weights increase
> w_nbq_wb the influence of links from
observations with few neighbours
• Binary weights vary the influence of
• Those with many neighbours are up-
weighted compared to those with few
Binary vs. row-standardized
• A binary weights matrix looks like: 0 1 0 0
0 0 1 1
1 1 0 0
0 1 1 1

• A row-standardized matrix it looks like: 0 1 0 0

0 0 .5 .5
.5 .5 0 0
0 .33 .33 .33
Style Options
Code Description
B basic binary coding
W row standardised (sums over all links to n)
C globally standardised (sums over all links to n)
U equal to C divided by the number of neighbours (sums over all
links to unity)

S the variance-stabilizing coding scheme

Regions with no neighbors
• If you ever get the following error:

Error in nb2listw(filename): Empty neighbor sets found

• You have some regions that have NO neighbors

> p_nbq_w<-nb2listw(p_nbq, zero.policy=T)

Step 3:
Examine spatial autocorrelation
Using spatial weights matrices, run statistical tests of spatial autocorrelation
Spatial autocorrelation
• Test for the presence of spatial autocorrelation
• Global
• Moran’s I
• Geary’s C
• Local (LISA – Local Indicators of Spatial Autocorrelation)
• Local Moran’s I and Getis Gi*

• We’ll just focus on the “industry standard” – Moran’s I

Autokorelasi Spasial
w <- poly2nb(p, row.names=p$Id)
plot(p, col='gray', border='blue', lwd=2)
plot(w, xy, col='red', lwd=2, add=TRUE)
wm <- nb2mat(w, style='B')
Autokorelasi Spasial


Menghitung Indeks Moran (1)
#compute Moran's Index pm <- matrix(yiyj, ncol=n)
pmw <- pm * wm
n <- length(p) pmw
y <- p$value spmw <- sum(pmw)
ybar <- mean(y) spmw
x smw <- sum(wm)
#####1st method sw <- spmw / smw
dy <- y - ybar vr <- n / sum(dy^2)
g <- expand.grid(dy, dy) MI <- vr * sw
yiyj <- g[,1] * g[,2] MI
EI <- -1/(n-1)
#####2nd method EI
yi <- rep(dy, each=n)
yj <- rep(dy)
yiyj <- yi * yj
Menghitung Indeks Moran (2)
#compute moran's using spdep function
ww <- nb2listw(w, style='B')

moran(p$value, ww, n=length(ww$neighbours), S0=Szero(ww))

#Note that
# is the same as
Moran’s I in R
> moran.test(p$value, listw=ww, randomisation=FALSE, alternative=‘less’)

“two.sided” → HA: I ≠ I0
“greater” → HA: I > I0
Diagram Pencar Moran
n <- length(p) reg <- lm(ams[,2] ~ ams[,1])
ms <- cbind(id=rep(1:n, each=n), abline(reg, lwd=2)
y=rep(y, each=n), abline(h=mean(ams[,2]), lt=2)
value=as.vector(wm * y))
abline(v=ybar, lt=2)
ms <- ms[ms[,3] > 0, ]
ams <- aggregate(ms[,2:3], list(ms[,1]),
FUN=mean) rwm <- mat2listw(wm, style='W')
ams <- ams[,-1] # Checking if rows add up to 1
colnames(ams) <- c('y', 'spatially lagged y') mat <- listw2mat(rwm)
head(ams) apply(mat, 1, sum)[1:15]
plot(ams) moran.plot(y, rwm)
Moran Scatter Plot
rwm <- mat2listw(wm, style='W')

# Checking if rows add up to 1

mat <- listw2mat(rwm)
apply(mat, 1, sum)

moran.plot(y, rwm)
Moran Scatter Plot
• Input data berikut:

• Input data bobot berikut:


Hitunglah indeks moran untuk data kemiskinan tsb!

• Mengubah data bobot ke dalam bentuk matriks

• Menghitung indeks moran global

moran(kemiskinan$Y, listw=w, n=112, S0=Szero(w))
• Menghitung indeks moran lokal
localmoran(kemiskinan$Y, w)

• Membuat Moran scatter plot

moran.plot(kemiskinan$Y, mat2listw(bot,style='W'),