Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In R, I'd like to calculate the straight-line distance between each capture of an animal in my dataset - no need to take into account the curvature of the earth. I have a dataset that looks like this:

record.nbr<- c(1:8)
individual<-  c(1,2,1,2,1,3,1,2)
captures<-data.frame(cbind(record.nbr, individual, x, y,

Here each "individual" represents a unique animal, and x/y points represent locations where the animals were captured. x/y points are UTM coordinates. Some individuals are caught many times, while other individuals are only captured once.

I'd like to calculate the distance (and the mean date) between recaptures by individual. In the output table, each row would summarize the distance between consecutive recaptures of an individual, plus the mean date between recaptures, like so:

individual first.rec  second.rec  distance
1          1             3        V         126
1          3             5        W         127.5
1          5             7        X         129
2          2             4        Y         126.5
3          4             6        Z         128
share|improve this question
up vote 5 down vote accepted

One way to do this is using ddply from the plyr package:

# split up captures by the unique individual id for processing
ddply(captures, "individual", function(df) {
  # single captures don't have any dist/time changes
  if(nrow(df)==1) {

  # for each pair of consecutive displacement, calculate dist and mean time
  out <- sapply(1:(nrow(df)-1), function(i) {
    d <- dist(df[i:(i+1),3:4])
    t <- mean(df[i:(i+1),5])
  out <- t(out)

  # reports results, adding the starting and ending record number
  # for each displacement
             end=tail(df$record.nbr, -1),

Which results in:

  individual start end      dist mean.time
1          1     1   3    290.00     126.0
2          1     3   5  49710.00     127.5
3          1     5   7  50000.02     129.0
4          2     2   4 283044.47     126.5
5          2     4   8 430217.62     128.5
6          3    NA  NA        NA        NA

The equivalent can be done using base tapply in R, however I generally find the ddply to be cleaner.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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