Is there a way to get the distances for the second nearest neighbor between two point patterns in R? The spatstat package has a function called nncross but it only applies to the nearest neighbors between two patterns and I need the distances to the second nearest neighbors.
3 Answers
The function get.knnx in package FNN can compute the N-nearest neighbours in point patterns.
x1 = cbind(runif(10),runif(10))
x2 = cbind(runif(10),runif(10))
nn = get.knnx(x1,x2,2)
now nn$nn.index is a matrix such that nn$nn.index[i,j] is the row in x1 of the two nearest neighbours to row i in x2 - sorted so that the nearest is [i,1], and the next neighbour is [i,2].
The function also returns the distances for you, and has some options to compute spatial indexes for very fast searches.
-
Thanks. Ran into a bit of a problem though. My data is of class 'ppp' ( for use with spatstat ). When I plug it into get.knnw, I get the following error> Error in get.knnx(rp, ponderosa, 2) : lists must be duplicated in .C– R.K.Jan 27, 2012 at 9:22
-
Just get the coordinates out using as.data.frame on your ppp object. Jan 27, 2012 at 11:57
-
Would nndist and nnwhich also be up for this task? Just noticed these two functions on the r-sig-geo list today... Jan 27, 2012 at 12:32
-
nndist and nnwhich only compute nearest distances within a single point pattern (which is what get.knn does), not from one type of points to another type of points (which is what get.knnx does). Also, get.knn is twice as fast as nndist if you use algorithm="kd_tree". Jan 27, 2012 at 13:56
-
@Spacedman Got it. Thanks man. I just saw crossdist. It seems to work like get.knnx. Will try it as well. I ended up using cbind and then getting the X and Y coordinates before I read your comment. Thanks a lot. R newbie here. Mostly a Python guy.– R.K.Jan 28, 2012 at 7:33
I just discovered that spatstat has a crossdist function.
Description
Computes the distances between pairs of ‘things’ taken from two different datasets.
It takes two point patterns X and Y as inputs, and returns the matrix whose [i,j] entry is the distance from X[i] to Y[j]. To get the second nearest neighbors using crossdist:
xdistances <- crossdist(X, Y) #Get all cross distances
nn = numeric()
for (i in 1:nrow(X)) {
xdistance <- sort(xdistances[i,], partial=2)[2]
nn <- append(nn, xdistance)
}
I know I already accepted Spacedman's answer but I would like to share how I did it in another way.
The function nndist
in the spatstat
package has an argument k
that determines the order of neighbours. To get the second nearest neighbour distance, use k=2
. To get both the first and the second neighbours, use k=1:2
.