24
votes

I'm starting with a SpatialPolygonsDataFrame which has the data to create a map of the districts of Ghana (available at http://www.diva-gis.org/datadown). I'm trying to create a matrix with the names of the districts as row and column names and 0s/1s in the interior to indicate if two districts are adjacent (neighboring) or not.

I've found several functions in spdep that seem promising, but I can't figure out how to use them for this purpose. I was able to create a "nb" file with the data using poly2nb, but am unsure how to proceed from here or even if I'm on the right track.

I'd really appreciate any help! Thank you!

2
This question probably should be asked to gis.stackexchange.com and closed here.user3710546
Nah, we got this :-) But, for future reference, @Pascal's right. That's a great place for R+GIS-related q's.hrbrmstr

2 Answers

35
votes

I think you're looking for gTouches:

library(rgeos)
library(rgdal)

# using http://data.biogeo.ucdavis.edu/data/diva/adm/GHA_adm.zip

ghana <- readOGR("GHA_adm", "GHA_adm1")

gTouches(ghana, byid=TRUE)

##       0     1     2     3     4     5     6     7     8     9
## 0 FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
## 1  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE
## 2  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE
## 3  TRUE  TRUE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
## 4 FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
## 5 FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE
## 6 FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE
## 7 FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE
## 8 FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE
## 9  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

On a quick glance, it looks right:

enter image description here

I'm not sure which Ghana administrative district file you are using, so that was a guess and those are in polygon order, so you'll need to poke at ghana@data and map the entries to admin district names.

23
votes

Please do not abuse rgeos. This is not a satisfactory answer - no district names. The original question was in any case trivial, as spdep::nb2mat() does this (with a little care with matrix row and column names):

library(spdep)
library(sp)
ghana <- readRDS("GHA_adm1.rds")
row.names(ghana) <- as.character(ghana$NAME_1)
nb <- poly2nb(ghana)
mat <- nb2mat(nb, style="B")
colnames(mat) <- rownames(mat)
mat

Using rgeos::gTouches() can work, especially if the returnDense=FALSE argument is used (ie. don't return a matrix), but can fail if snapping is needed. spdep::poly2nb() is the preferred route, because it makes snapping possible, and because the nb S3 class is much more flexible than matrices.

It is possible to prime spdep::poly2nb() with the output of rgeos::gUnarySTRtreeQuery(), which provides lists of polygons with overlapping bounding boxes as candidate neighbours. This handles really large data sets fast.

You can also post questions relating to R-spatial on R-sig-geo.