1
votes

I have a function where I am calculating the index of the minimum distance between a lat/long coordinate (in SpatialPoints) and another vector of coordinates (also in SpatialPoints). The function I use to find min dist is:

library(rgeos)
dfdist$mindist <-apply(gDistance(sp1, sp2, byid=TRUE), 1, which.min)

The function above gives me a column mindist in my pre-existing data frame dfdist which is an index of the row number of the point where the minimum distance occurs.

I'd like to also find the 2nd min distance, and the 3rd min dist, but am unsure of how to do this with the apply(). Is there a replacement for the which.min which will give me the index of the second min? Third min?

2
Maybe combine which with rank? As in: which(rank(your_data)==2). Be aware of ties, though.coffeinjunky

2 Answers

1
votes

You can use this user-defined function to do so:

f_which.min <- function(vec, idx) sort(vec, index.return = TRUE)$ix[idx]

So you can use:

apply(gDistance(sp1, sp2, byid=TRUE), 1, f_which.min, idx = 1) 

Set the argument idx accordingly. That is, idx=1 first min, idx=2 second min and so on.

0
votes

I would use functions like the following:

which_nmin <- function(x, n = 1) 
{
  ux <- unique(x)
  ux <- ux[order(ux)][n]
  which(x == ux)
}

which_nmin(c(1, 1, 1, 1:5), 3)


which_nmax <- function(x, n = 1) 
{
  ux <- unique(x)
  ux <- ux[order(ux, decreasing = TRUE)][n]
  which(x == ux)
}

which_nmax(c(1, 1, 1, 1:5), 2)

Your apply call would be

apply(gDistance(sp1, sp2, byid=TRUE), 1, which_nmin, n = 2)