# How to get the second nearest neighbor between two point patterns in R?

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 '12 at 9:22
• Just get the coordinates out using as.data.frame on your ppp object. – Spacedman Jan 27 '12 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... – Roman Luštrik Jan 27 '12 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". – Spacedman Jan 27 '12 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 '12 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)
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`.