8

I have a SpatialPointsDataFrame that I'm working with in R. I want to add a new vector to the dataframe that contains, for every point, the distance to the nearest other point in the SpatialPointsDataFrame. I've looked at knearneigh in the spdep package as well as spDistsN1 and spDists in the sp package, but neither of those give me exactly what I want. To be clear, all of these points are in ONE SpatialPointsDataFrame.

1

1 Answer 1

13

There are several ways you can tackle this in R, including spDists in sp and gDistance in rgeos. An efficient way, that is expandable to multiple kNN ID's and distances, is to use spdep.

require(spdep)
data(meuse)
coordinates(meuse) = ~x+y
  meuse <- meuse[1:10,]
    meuse@data$IDS <- 1:10

# Neighbor row indices and add neighbor attribute ID's   
( knn1 <- knearneigh(coordinates(meuse), k=1)$nn )
  meuse@data$nnID <- meuse@data[knn1,]$IDS 

# Add neighbor distance
meuse.dist <- dnearneigh(coordinates(meuse), 0, 1000)
  dist.list <- nbdists(meuse.dist, coordinates(meuse))
    meuse@data$nnDist <- unlist(lapply(dist.list, FUN=function(x) min(x)))

meuse@data

Another, very fast way, is the nabor package. Since distance is returned along with the neighbor ID you can add both simultaneously. The nabor::knn function does return self-neighbors so, you have to set k to >= 2 and drop the first column in the resulting matrices. One advantage here is that, as long as the matrices are the same dimension, you can get neighbors from the same or independent data.

library(nabor)
library(sp)

data(meuse)
coordinates(meuse) = ~x+y
  meuse <- meuse[1:10,]
    meuse@data$IDS <- 1:10

knn1 <- knn( coordinates(meuse), coordinates(meuse), k=2)
  ( knn1 <- data.frame( knn=knn1[[1]][,2], knn.dist=knn1[[2]][,2] ) )   

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.