Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spatial weights: asymmetric adjacency matrix?

I am creating an adjacency matrix to do spatial analysis in R. The data are all counties in the continental US. I've got the counties spatial polygons from US Census Tiger files.

I am able to create the neighbors list, and it is symmetric. But when I convert that to an adjacency matrix it is not symmetric. This is a problem because my goal is to run a spatial autologistic model using ngspatial::autologistic, and I get an error that I must supply a symmetric binary adjacency matrix.

Here is my R code to create the adjacency matrix:

us<-readShapeSpatial("County_2010Census_DP1.shp")
#Trim out counties outside of continental US
us2<-us[!substr(us$GEOID10,1,2)%in%c('02','60','66','78','15','72'),]
us2.nb = poly2nb(us2)
is.symmetric.nb(us2.nb) #Comes out true
us2.adj = nb2mat(us2.nb, style="B",zero.policy=F)
isSymmetric(us2.adj) #comes out false

As an aside, I am able to use splogit with this adjacency matrix without a problem. I'm no expert on spatial analysis, so I can't say I know what is going on within these commands.

like image 400
robin.datadrivers Avatar asked Oct 19 '22 21:10

robin.datadrivers


1 Answers

The matrix us2.adj is symmetric. The problem is with the test. It turns out that

isSymmetric(us2.adj)

uses all.equal(...) to test for equality of the matrix with it's transpose, and all.equal(...) checks the attributes as well as the values. nb2mat(...) creates a matrix with the row names set to the polygon IDs and the column names unset. So all.equal(...) returns FALSE and therefore so does isSymmetric(...). Evidently, the autologistic(...) function uses this same test.

us2.adj <- nb2mat(us2.nb, style="B",zero.policy=F)
isSymmetric(us2.adj)
# [1] FALSE
isSymmetric(us2.adj,check.attributes=FALSE)
# [1] TRUE

The simple solution is to either set the columns names to the row names, or set the row names to NULL.

x <- us2.adj
colnames(x) <- rownames(x)
isSymmetric(x)
# [1] TRUE
y <- us2.adj
rownames(y) <- NULL
isSymmetric(y)
# [1] TRUE

BTW, I think the reason this question went unanswered for 18 hours is that you did not provide a link to your shapefile. If you do not provide a reproducible example, the tendency is for members to ignore or downvote the question. See this link for instructions

like image 131
jlhoward Avatar answered Oct 22 '22 22:10

jlhoward