0

I'm trying to get the overall distance that an animal traveled by using a function that uses differences in lat long positions to output a distance traveled. Having some issues with nested loops.

The function ComputeDistance takes the arguments Lat1, Lat2, Long1, Long 2 in that order. Column 5 of DistTest contains latitude values and 6 contains longitude values.

So for the object "output", I'm trying to get sequential distances going through all 38 rows.

e.g. ComputeDistance(DistTest[1,5],DistTest[2,5],DistTest[1,6],DistTest[2,6] followed by: ComputeDistance(DistTest[2,5],DistTest[3,5],DistTest[2,6],DistTest[3,6] followed by: ComputeDistance(DistTest[3,5],DistTest[4,5],DistTest[3,6],DistTest[4,6] .... ComputeDistance(DistTest[37,5],DistTest[38,5],DistTest[37,6],DistTest[38,6]

I'm thinking that the problem is that the loop is going through every possible combination of DL and EL, not just going sequentially in order.

Below is the code I'm using currently.

## rows 1-37 and rows 2-38
DL <- 1:37
EL <- 2:38




## subsetting for one tagged animal
DistTest <- subset(Dispsum, Tag.ID == 1658)

## creating blank objects to save output in
testid <- c()
testdistance <- c()

for( j in DL){
  for( k in EL){

    output <- (ComputeDistance(DistTest[j,5], DistTest[k,5],DistTest[j,6], DistTest[k,6]))
    Name <- 1658
    testid <- rbind(testid, Name)
    testdistance <- rbind(testdistance,output)


    }
  }
C. Braun
  • 5,061
  • 19
  • 47
ljh2001
  • 391
  • 3
  • 17

1 Answers1

0

Generally in R, it is better to find functions that do the looping for you, as most of them are set up for that. In this case, you can try using mutate and lead from the dplyr package:

library(dplyr)

df <- dplyr::tibble(lat = 1:5, lon = 5:1)
df
# A tibble: 5 x 3
#     lat   lon distance
#   <int> <int>    <dbl>
# 1     1     5     1.41
# 2     2     4     1.41
# 3     3     3     1.41
# 4     4     2     1.41
# 5     5     1    NA   

df %>% mutate(distance = ComputeDistance(lat, lead(lat), lon, lead(lon)))
# A tibble: 5 x 3
#      lat   lon distance
#    <int> <int>    <dbl>
#  1     1    10     1.41
#  2     2     9     1.41
#  3     3     8     1.41
#  4     4     7     NA

If you really want to stick with for loops, you only need one for this problem. You were right in saying that you're going through every combination. One alternative would be:

for (i in 1:37) {
    output <- ComputeDistance(DistTest[i, 5], DistTest[i + 1, 5],
                              DistTest[i, 6], DistTest[i + 1, 6])
    Name <- 1658
    testid <- rbind(testid, Name)
    testdistance <- rbind(testdistance, output)
}

One reason to avoid this construct is that you are incrementally growing an object (see here for more about that).

C. Braun
  • 5,061
  • 19
  • 47