Nearest Neighbor Analysis

1. Introducing PPP format

rm(list = ls())
library(sf)
警告: 套件 ‘sf’ 是用 R 版本 4.3.3 來建造的
library(tmap)
警告: 套件 ‘tmap’ 是用 R 版本 4.3.3 來建造的
library(ggplot2)
library(spatstat)
警告: 套件 ‘spatstat’ 是用 R 版本 4.3.3 來建造的警告: 套件 ‘spatstat.data’ 是用 R 版本 4.3.3 來建造的警告: 套件 ‘spatstat.univar’ 是用 R 版本 4.3.3 來建造的警告: 套件 ‘spatstat.geom’ 是用 R 版本 4.3.3 來建造的警告: 套件 ‘spatstat.random’ 是用 R 版本 4.3.3 來建造的警告: 套件 ‘spatstat.explore’ 是用 R 版本 4.3.3 來建造的警告: 套件 ‘spatstat.model’ 是用 R 版本 4.3.3 來建造的警告: 套件 ‘spatstat.linnet’ 是用 R 版本 4.3.3 來建造的
# setwd("C:/data")
schools_sf <- st_read("./Data/Schools.shp")
Reading layer `Schools' from data source `C:\Users\wenth\Desktop\WK07\Data\Schools.shp' using driver `ESRI Shapefile'
Simple feature collection with 424 features and 10 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 155883.3 ymin: 2535008 xmax: 207754.3 ymax: 2588596
Projected CRS: TWD97 / TM2 zone 121
TN_BND_sf <- st_read("./Data/TainanCounty.shp")
Reading layer `TainanCounty' from data source 
  `C:\Users\wenth\Desktop\WK07\Data\TainanCounty.shp' using driver `ESRI Shapefile'
Simple feature collection with 1 feature and 1 field
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 149892.7 ymin: 2531586 xmax: 215203.6 ymax: 2590609
Projected CRS: TWD97 / TM2 zone 121
# head(county_sf)

# method-1
bnd <-st_bbox(schools_sf)
x.coor<-schools_sf$X_coor
y.coor<-schools_sf$Y_coor
x.range<-c(bnd[1]-10,bnd[3]+10) 
y.range<-c(bnd[2]-10,bnd[4]+10)
schools_pp1 <- ppp(x.coor,y.coor,x.range,y.range)
plot(schools_pp1)


# method-2
Coord <- st_coordinates(schools_sf)
Windows <- as.owin(TN_BND_sf)
schools_pp2 <- as.ppp(Coord, Windows)
plot(schools_pp2)

2. Nearest neighbor distance

# calculating the area
x<-x.range[2]-x.range[1]
y<-y.range[2]-y.range[1]
sqr.area<- x*y

nnd <- nndist(schools_pp1, k=1)
d1<-mean(nnd) # Tainan School
rd<- 0.5/sqrt(424/sqr.area)  # theoretical random pattern
r.scale <- d1/rd

3. K-order Nearest Neighbor Distance

mean(nndist(schools_pp1, k=2))
[1] 1433.762
ANN <- apply(nndist(schools_pp1, k=1:20),2,FUN=mean) # margin=2: columns
xValue= 1:20
yValue <- ANN
df1 <- data.frame(xValue,yValue)
ggplot(data=df1,aes(x=xValue, y=yValue))+ geom_line() + geom_point() + 
      xlab("K-order NN") +  ylab("distance") +
      ggtitle("Average K-order NN Distance")

4. G(d) function

G = ecdf(nnd) 
plot(G, main="G function", xlim=c(0,5000))

5. Comparing with a random pattern

TN.Windows<-owin(xrange=x.range, yrange=y.range)
nn1<-rpoint(424, win=TN.Windows)
plot(nn1, pch=16, size=0.5)


nnd1<-nndist(nn1, k=1)
G1 = ecdf(nnd1) 
plot(G, main="G function", xlim=c(0,5000))
lines(G1,col='blue')

6. Generating Random Points

Windows <- as.owin(TN_BND_sf)
nn2<- rpoint(415, win = Windows)
plot(nn2, pch=16, size=0.5) 

LS0tDQp0aXRsZTogIlNwYXRpYWwgQW5hbHlzaXM6IDA3Ig0KYXV0aG9yOiAiVHphaS1IdW5nIFdlbiINCmRhdGU6ICcyMDI1LTA0LTIxJw0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogNg0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KLS0tDQoNCiMjIE5lYXJlc3QgTmVpZ2hib3IgQW5hbHlzaXMNCg0KIyMjIDEuIEludHJvZHVjaW5nIFBQUCBmb3JtYXQNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0V9DQpybShsaXN0ID0gbHMoKSkNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KHRtYXApDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHNwYXRzdGF0KQ0KDQojIHNldHdkKCJDOi9kYXRhIikNCnNjaG9vbHNfc2YgPC0gc3RfcmVhZCgiLi9EYXRhL1NjaG9vbHMuc2hwIikNClROX0JORF9zZiA8LSBzdF9yZWFkKCIuL0RhdGEvVGFpbmFuQ291bnR5LnNocCIpDQojIGhlYWQoY291bnR5X3NmKQ0KDQojIG1ldGhvZC0xDQpibmQgPC1zdF9iYm94KHNjaG9vbHNfc2YpDQp4LmNvb3I8LXNjaG9vbHNfc2YkWF9jb29yDQp5LmNvb3I8LXNjaG9vbHNfc2YkWV9jb29yDQp4LnJhbmdlPC1jKGJuZFsxXS0xMCxibmRbM10rMTApIA0KeS5yYW5nZTwtYyhibmRbMl0tMTAsYm5kWzRdKzEwKQ0Kc2Nob29sc19wcDEgPC0gcHBwKHguY29vcix5LmNvb3IseC5yYW5nZSx5LnJhbmdlKQ0KcGxvdChzY2hvb2xzX3BwMSkNCg0KIyBtZXRob2QtMg0KQ29vcmQgPC0gc3RfY29vcmRpbmF0ZXMoc2Nob29sc19zZikNCldpbmRvd3MgPC0gYXMub3dpbihUTl9CTkRfc2YpDQpzY2hvb2xzX3BwMiA8LSBhcy5wcHAoQ29vcmQsIFdpbmRvd3MpDQpwbG90KHNjaG9vbHNfcHAyKQ0KYGBgDQoNCg0KIyMjIDIuIE5lYXJlc3QgbmVpZ2hib3IgZGlzdGFuY2UNCg0KYGBge3J9DQojIGNhbGN1bGF0aW5nIHRoZSBhcmVhDQp4PC14LnJhbmdlWzJdLXgucmFuZ2VbMV0NCnk8LXkucmFuZ2VbMl0teS5yYW5nZVsxXQ0Kc3FyLmFyZWE8LSB4KnkNCg0Kbm5kIDwtIG5uZGlzdChzY2hvb2xzX3BwMSwgaz0xKQ0KZDE8LW1lYW4obm5kKSAjIFRhaW5hbiBTY2hvb2wNCnJkPC0gMC41L3NxcnQoNDI0L3Nxci5hcmVhKSAgIyB0aGVvcmV0aWNhbCByYW5kb20gcGF0dGVybg0Kci5zY2FsZSA8LSBkMS9yZA0KDQpgYGANCg0KDQojIyMgMy4gSy1vcmRlciBOZWFyZXN0IE5laWdoYm9yIERpc3RhbmNlDQoNCmBgYHtyfQ0KbWVhbihubmRpc3Qoc2Nob29sc19wcDEsIGs9MikpDQoNCkFOTiA8LSBhcHBseShubmRpc3Qoc2Nob29sc19wcDEsIGs9MToyMCksMixGVU49bWVhbikgIyBtYXJnaW49MjogY29sdW1ucw0KeFZhbHVlPSAxOjIwDQp5VmFsdWUgPC0gQU5ODQpkZjEgPC0gZGF0YS5mcmFtZSh4VmFsdWUseVZhbHVlKQ0KZ2dwbG90KGRhdGE9ZGYxLGFlcyh4PXhWYWx1ZSwgeT15VmFsdWUpKSsgZ2VvbV9saW5lKCkgKyBnZW9tX3BvaW50KCkgKyANCiAgICAgIHhsYWIoIkstb3JkZXIgTk4iKSArICB5bGFiKCJkaXN0YW5jZSIpICsNCiAgICAgIGdndGl0bGUoIkF2ZXJhZ2UgSy1vcmRlciBOTiBEaXN0YW5jZSIpDQoNCmBgYA0KDQoNCiMjIyA0LiBHKGQpIGZ1bmN0aW9uDQoNCmBgYHtyfQ0KRyA9IGVjZGYobm5kKSANCnBsb3QoRywgbWFpbj0iRyBmdW5jdGlvbiIsIHhsaW09YygwLDUwMDApKQ0KDQpgYGANCg0KDQoNCiMjIyA1LiBDb21wYXJpbmcgd2l0aCBhIHJhbmRvbSBwYXR0ZXJuDQoNCmBgYHtyfQ0KVE4uV2luZG93czwtb3dpbih4cmFuZ2U9eC5yYW5nZSwgeXJhbmdlPXkucmFuZ2UpDQpubjE8LXJwb2ludCg0MjQsIHdpbj1UTi5XaW5kb3dzKQ0KcGxvdChubjEsIHBjaD0xNiwgc2l6ZT0wLjUpDQoNCm5uZDE8LW5uZGlzdChubjEsIGs9MSkNCkcxID0gZWNkZihubmQxKSANCnBsb3QoRywgbWFpbj0iRyBmdW5jdGlvbiIsIHhsaW09YygwLDUwMDApKQ0KbGluZXMoRzEsY29sPSdibHVlJykNCmBgYA0KDQoNCiMjIyA2LiBHZW5lcmF0aW5nIFJhbmRvbSBQb2ludHMNCg0KYGBge3J9DQpXaW5kb3dzIDwtIGFzLm93aW4oVE5fQk5EX3NmKQ0Kbm4yPC0gcnBvaW50KDQxNSwgd2luID0gV2luZG93cykNCnBsb3Qobm4yLCBwY2g9MTYsIHNpemU9MC41KSANCg0KYGBgDQoNCg==