[R-sig-Geo] creating cluster with between-points arbitrary distances

Dan Putler dan.putler at sauder.ubc.ca
Thu Dec 10 08:23:04 CET 2009

Hi Alexandre,

Greetings from yesterday evening.

I think I know what you want, and I've been working on the same problem
in a very different substantive context. To make sure I understand the
question, you are basically stating that if the gap between "nearest"
birds of the same species exceeds 1000 meters, then the two birds cannot
be considered to be in the same cluster. Returning to your example of
birds along a straight line, assume the birds run from A to B to C, and
A and B are 700 meters apart, while B and C are 1001 meters apart, then
it is the case that A and B are in a cluster, but C is not a member of
that cluster.

Assuming what I said is correct, one thing you can do is create a
relative neighbor graph of your points, and then drop any edges from the
graph that exceed 1000 meters. This will create a set up unconnected
sub-graphs, and the points within each sub-graph constitutes a cluster.
I've written a function (using the spdens package) that removes the long
edges from the relative neighbor graph, there by creating the set of
clusters. I've pasted my function below (at some point I will create an
R package that includes this function, but it is likely a couple of
months away).

The function follows:

# dropLongLinks takes an nb (neighbor list) object, the original
# and a maximum distance, then removes links from the nb object for
links that
# exceed the maximum distance.

# Programer: Dan Putler
# Created: 08Feb09
# Modified: 08Feb09

dropLongLinks <- function(nb, coords, max.dist) {
    if(!is.matrix(coords)) coords <- as.matrix(coords)
    dists <- nbdists(nb, coords)
    nb.new <-
      lapply(1:length(nb), function(i) nb[[i]] <- nb[[i]][dists[[i]] <=
    class(nb.new) <- "nb"

On Thu, 2009-12-10 at 07:50 +0100, Alexandre VILLERS wrote:
> Good morning (and sorry for the cross posting on the R sig ecology),
> I'm still working on the spatial distribution of an aggregated bird species. I would like to test different between birds distances to create clusters and thus identify groups of birds (leks). It would be "visually" quite easy to do it but I would like to repeat this clustering objectively for many years in order to characterize some biological processes. So I would like for example to group all the birds who share neighbours in less than 1000 meters in the same cluster. Thus, 3 birds lying on a straight line 700 meters from each other would belong to the same cluster (hope this is clear).
> I can get groups of points whose distances are below a certain threshold with dnearneigh() from package "spdep" but this would still require to write an iterative function to group points. 
> Is there an existing function that can do the whole trick? I know many packages are available for clustering with R but I haven't found one that I can parametrize in a such way yet.
> Any link will be appreciated.
> Thanks
> Alex
> P.S.: to get this visually
> x<-c(0,700,1400, 3000)
> y<-c(0,0,0,0)
> plot(y~x, col=c("red","red", "red", "black"), pch=c(16,16,16,16)) # red points belong to the same cluster while the black doesn't
Dan Putler
Sauder School of Business
University of British Columbia

More information about the R-sig-Geo mailing list