反距离权重是最符合人们对空间关系认知的一种模型,也是所谓“地理学第一定律”最经典的解答:相互之间的距离越大,权重就越小。而距离的越近,影响权重就越大。
在ArcGIS里面,反距离权重是所有空间统计统计默认的方法,但是在R语言里面,确需要手动去进行一下设置。在讲反距离权重之前,先看看如何设定临近要素的范围。
如果是K临近这种方法就不用说了,K临近唯一的参数就是忽略距离,去旋转周边最近的N个要素为自己的临近要素,但是如果用共点共边这样的关系,因为实际上的地理情况,会出现所谓的独立要素,比如中国行政区划做共点共边的话,台湾和海南默认肯定是独立要素。
虽然我们可以自定义空间关系,来解决独立要素的问题,但是也会有人有疑问,我可不可以设定一个范围,比如100公里,那么100公里之内的所有要素,都认为是临近要素呢?没问题,R语言定义空间关系的时候,加一个参数就可以了,如下:我定义了不同范围内的空间关系:

在1度范围内,可以看见海南已经与广东是临近关系了,而到来度,台湾与福建也成为临近关系了。当我把范围扩展到30度(最后一幅图),发现国内所有省份之间,相互全部都是临近关系,这样就变成了全要素集合了。
这个距离范围,如果是面状要素的话,用的两个面最近的位置来计算的,而不是用的中心点,比如第二幅,1度范围的,我们看新疆和内蒙就知道,他们两个的中心点,绝对不止100公里,但是实际上设置100公里范围内,他们就变成了相邻要素,是因为新疆最东边的哈密地区伊吾县到内蒙最西边的阿拉善盟额济纳旗只有70多公里:

计算及绘制上面图形的代码如下:
library("sp")
library("maptools")
library("spdep")
path <- "E:\\workspace\\IDE\\Rworkspace\\空间分析\\空间权重矩阵\\china\\"
#将中国的省级行政区划读取为ploygon
cnData <- readShapePoly(paste(path,"CNPG_S.shp",sep =""))
#定义投影为wgs84
proj4string(cnData) <- "+proj=longlat +datum=WGS84"
#定义唯一标识符,用省级行政区划的编码
IDs <- cnData@data$Code
#将名称转换为gbk编码
cnData$FIRST_NAME <- iconv(cnData$FIRST_NAME,"UTF-8","GBK")
par(mfrow=c(3,2),mar=c(0,0,1,0))
#不同范围:
#1、默认范围(触点连接)
w_cn1 <- poly2nb(cnData, queen=T)
plot(cnData)
points(map_crd,col='red',pch='*')
plot(nb2listw(w_cn1,zero.policy=TRUE),coords=coordinates(cnData), cex=0.1, col="blue", add=T)
title("默认范围(触点连接)")
#2、1度范围(约108公里)
w_cn2 <- poly2nb(cnData, queen=T,snap = 1)
plot(cnData)
points(map_crd,col='red',pch='*')
plot(nb2listw(w_cn2,zero.policy=TRUE),coords=coordinates(cnData), cex=0.1, col="blue", add=T)
title("1度范围(约108公里)")
#3、2度范围(约210公里)
w_cn3 <- poly2nb(cnData, queen=T,snap = 2)
plot(cnData)
points(map_crd,col='red',pch='*')
plot(nb2listw(w_cn3,zero.policy=TRUE),coords=coordinates(cnData), cex=0.1, col="blue", add=T)
title("2度范围(约210公里)")
#4、3度范围(约320公里)
w_cn4 <- poly2nb(cnData, queen=T,snap = 3)
plot(cnData)
points(map_crd,col='red',pch='*')
plot(nb2listw(w_cn4,zero.policy=TRUE),coords=coordinates(cnData), cex=0.1, col="blue", add=T)
title("3度范围(约320公里)")
#5、10度范围(约1000公里)
w_cn5 <- poly2nb(cnData, queen=T,snap = 10)
plot(cnData)
points(map_crd,col='red',pch='*')
plot(nb2listw(w_cn5,zero.policy=TRUE),coords=coordinates(cnData), cex=0.1, col="blue", add=T)
title("10度范围(约1000公里)")
#6、30度范围(约3000公里)
w_cn6 <- poly2nb(cnData, queen=T,snap = 30)
plot(cnData)
points(map_crd,col='red',pch='*')
plot(nb2listw(w_cn6,zero.policy=TRUE),coords=coordinates(cnData), cex=0.1, col="blue", add=T)
title("30度范围(约3000公里)")
这种情况下定义的所有临近要素的权重都是一样,有多少个临近要素,就把权重均为多少份,比如北京:有两个临近要素,天津和河北,那么他们的权重就正好都是0.5
实际上我们希望的是按照不同的距离来设定不同的权重(当然,这个权重也可以手动设置,以后再说)。
但是如果按照面要素的边界而论,触点连接,表示是无缝的面临接,所以如果按照边界距离,那肯定是0,0作为分母的话,权重就无穷大了。所以在面要素的距离计算中,通常用几何中心点来作为位置进行计算。
我们放大北京、河北、天津三个城市的区域,来看看他们的几何中心点:
因为河北省的奇葩形状,所以几何中心几乎就在北京区域内了……从距离上看,河北到北京的距离是要小于天津到北京的,那么几何中心实际上有些不太合理的,所以还有另外一种方法,就是用省会来进行计算,这个我们以后再说。
在R语言的spdep包里面,提供了这样一个方法,来计算距离:(相应的参数,大家自行查看文档)
第一行就可以看出,北京的几何中心离天津大约是126.5公里,离河北是67.4公里。这是所谓的正距离,而我们需要的是反距离,也就是距离的倒数,距离越大,权重越小,所以,将所有的距离都取倒数:
当然,在反距离的基础上,还也增加距离的幂……这幂用于决定,是否要强调距离的作用,如下所示:
幂越大,表示距离的作用越大,曲线也越陡峭。
下面我们把幂设为2,看看结果:
下面就可以根据计算出来的距离,来分配不同的权重了:
以上计算的语句如下:计算出距离之后,利用glist参数,将距离作为权重,设置到临近要素空间权重列表中:
w_cn <- poly2nb(cnData, queen=T)
map_crd <- coordinates(cnData)
dlist <- nbdists(w_cn, map_crd[,c(1,2)], longlat = T)
dlist_p1 <- lapply(dlist, function(x) 1/x)
dlist_p2 <- lapply(dlist, function(x) 1/(x*x))
w_cn_mat <- nb2listw(w_cn,zero.policy=TRUE)
w_cn_mat_d <- nb2listw(w_cn, glist=dlist, zero.policy=TRUE)
w_cn_mat_d_p1 <- nb2listw(w_cn, glist=dlist_p1, zero.policy=TRUE)
w_cn_mat_d_p2 <- nb2listw(w_cn, glist=dlist_p2, zero.policy=TRUE)
可视化如下:(可以点开看大图)
绘制语句如下:
library(leaflet)
par(mfrow=c(2,2),mar=c(0,0,1,0), bg="black")
w1<-c()
for(i in w_cn_mat$weights){
w1 <- c(w1,i)
}
pal1 <- colorNumeric(c("blue", "darkgreen", "yellow", "orangered"), w1)
plot(cnData,border="grey")
points(map_crd,col='red',pch='*')
plot(w_cn_mat,coords=coordinates(cnData), cex=0.1, col=pal1(w1), add=T)
title("默认共点共边",col.main= "white")
w2<-c()
for(i in w_cn_mat_d$weights){
w2 <- c(w2,i)
}
pal2 <- colorNumeric(c("blue", "darkgreen", "yellow", "orangered"), w2)
plot(cnData,border="grey")
points(map_crd,col='red',pch='*')
plot(w_cn_mat_d,coords=coordinates(cnData), cex=0.1, col=pal2(w2), add=T)
title("正距离权重",col.main= "white")
w3<-c()
for(i in w_cn_mat_d_p1$weights){
w3 <- c(w3,i)
}
pal3 <- colorNumeric(c("blue", "darkgreen", "yellow", "orangered"), w3)
plot(cnData,border="grey")
points(map_crd,col='red',pch='*')
plot(w_cn_mat_d_p1,coords=coordinates(cnData), cex=0.1, col=pal3(w3), add=T)
title("反距离权重:幂为1",col.main= "white")
w4<-c()
for(i in w_cn_mat_d_p2$weights){
w4 <- c(w4,i)
}
pal4 <- colorNumeric(c("blue", "darkgreen", "yellow", "orangered"), w4)
plot(cnData,border="grey")
points(map_crd,col='red',pch='*')
plot(w_cn_mat_d_p2,coords=coordinates(cnData), cex=0.1, col=pal4(w4), add=T)
title("反距离权重:幂为2",col.main= "white")