25

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!

Megan E.
  • 317
  • 1
  • 3
  • 7
  • 2
    This question probably should be asked to http://gis.stackexchange.com and closed here. –  Oct 22 '14 at 01:34
  • Nah, we got this :-) But, for future reference, @Pascal's right. That's a great place for R+GIS-related q's. – hrbrmstr Oct 22 '14 at 01:54

2 Answers2

35

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.

hrbrmstr
  • 77,368
  • 11
  • 139
  • 205
23

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.

Konrad
  • 17,740
  • 16
  • 106
  • 167
Roger Bivand
  • 551
  • 3
  • 2
  • 2
    I'm not sure this answers the question. – Stuart Siegler Aug 31 '15 at 19:20
  • 6
    if you have a complaint or guidance for users, please post on meta (once you have 5 rep) but don't put that noise in your answer because that irritates others which seems something you like to avoid. – rene Aug 31 '15 at 19:24
  • I think this answer is helpfull if you need polygon snapping (in case of white space between polygons or borders not exactly matching). I was using the original answer with gTouches and was getting less neighbors than I was expecting. Maybe if the answer was edited to make that clear it would help. – eclark Jun 14 '17 at 23:22