1

Apologies if a similar query has been posted - couldn't find it.

I have GPS locations (UTM) for multiple individuals.

       X       Y AnimalID      DATE
1 550466 4789843       10 1/25/2008
2 550820 4790544       10 1/26/2008
3 551071 4791230       10 1/26/2008
4 550462 4789292       10 1/26/2008
5 550390 4789934       10 1/27/2008
6 550543 4790085       10 1/27/2008

I am attempting to calculate Net Squared Displacement and once NSD has reached at least 800m, I'd like to repeat the formula starting at 0 at the next row.

Desired output is this:

     XLOC    YLOC ANIMALID        DATETIME Xdist Ydist  NSD GROUP
1  550466 4789843       10 1/25/2008 17:00   354   701  785     1
2  550820 4790544       10  1/26/2008 1:00   605  1387 1513     1
3  551071 4791230       10  1/26/2008 9:00   609  1938 2031     2
4  550462 4789292       10 1/26/2008 17:00    72   642  646     3
5  550390 4789934       10  1/27/2008 1:00    81   793  797     3
6  550543 4790085       10  1/27/2008 9:00    82   149  170     3
7  550380 4789441       10 1/27/2008 17:00   178   192  262     3
8  550284 4789484       10  1/28/2008 1:00   559   426  703     3
9  549903 4789718       10  1/28/2008 9:00     0    35   35     3
10 550462 4789327       10 1/28/2008 17:00   574   275  636     3
11 549888 4789567       10  1/29/2008 1:00   532   263  593     3
12 549930 4789555       10  1/29/2008 9:00    65     4   65     3
13 550397 4789288       10 1/29/2008 17:00   124   140  187     3
14 550338 4789432       10  1/30/2008 1:00   554   339  649     3
15 549908 4789631       10  1/30/2008 9:00    84    75  113     3
16 550378 4789367       10 1/30/2008 17:00   657  1876 1988     3
17 550414 4789354       10  1/31/2008 1:00   531    91  539     4
18 549883 4789445       10  1/31/2008 9:00   188   136  232     4
19 550226 4789490       10 1/31/2008 17:00   126   141  189     4
20 550288 4789495       10   2/1/2008 1:00   176   187  257     4

I added the 'Group' column to indicate when 800 NSD was attained.

I'm really struggling with how exactly to code for this particular approach mainly because the first UTM has to be identical until 800m has been reached.

In other words, I can't do this:

xdist<-abs(diff(X)
ydist<-abs(diff(Y)
nsd<-sqrt(xdist^2+ydist^2)

I need to do this until the target of 800m was reached:

xdist <- abs(X in row 2 - 550446)
ydist <- abs(Y in row 2 - 4789843)

Then the unique UTMs will need to be from rows 3, 4, 17 and so on.

I hope this makes sense and I'd appreciate any help!

odocoileus
  • 53
  • 7

1 Answers1

0

I think this is what you are looking for:

data$GROUP[1] <- 1
data$Xdist[1] <- data$XLOC[2] - data$XLOC[1]
data$Ydist[1] <- data$YLOC[2] - data$YLOC[1]
data$NSD[1]   <- as.integer(sqrt(data$Xdist[1]^2+data$Ydist[1]^2))
for ( i in 2:(nrow(data)-1)) {
  if ( data$NSD[i-1] > 800) {
    data$Xdist[i] <- data$XLOC[i+1] - data$XLOC[i]
    data$Ydist[i] <- data$YLOC[i+1] - data$YLOC[i]
    data$NSD[i]   <- as.integer(sqrt(data$Xdist[i]^2+data$Ydist[i]^2))
    data$GROUP[i] <- (data$GROUP[i-1] + 1)
  } else {
    data$Xdist[i] <- data$XLOC[i+1] - data$XLOC[i] + data$Xdist[i-1]
    data$Ydist[i] <- data$YLOC[i+1] - data$YLOC[i] + data$Ydist[i-1]
    data$NSD[i]   <- as.integer(sqrt(data$Xdist[i]^2+data$Ydist[i]^2))
    data$GROUP[i] <- (data$GROUP[i-1])    
  }
}

output:

> data
     XLOC    YLOC ANIMALID       DATE  TIME Xdist Ydist  NSD GROUP
1  550466 4789843       10 1/25/20081  7:00   354   701  785     1
2  550820 4790544       10  1/26/2008  1:00   605  1387 1513     1
3  551071 4791230       10  1/26/2008  9:00  -609 -1938 2031     2
4  550462 4789292       10  1/26/2008 17:00   -72   642  646     3
5  550390 4789934       10  1/27/2008  1:00    81   793  797     3
6  550543 4790085       10  1/27/2008  9:00   -82   149  170     3
7  550380 4789441       10  1/27/2008 17:00  -178   192  261     3
8  550284 4789484       10  1/28/2008  1:00  -559   426  702     3
9  549903 4789718       10  1/28/2008  9:00     0    35   35     3
10 550462 4789327       10  1/28/2008 17:00  -574   275  636     3
11 549888 4789567       10  1/29/2008  1:00  -532   263  593     3
12 549930 4789555       10  1/29/2008  9:00   -65    -4   65     3
13 550397 4789288       10  1/29/2008 17:00  -124   140  187     3
14 550338 4789432       10  1/30/2008  1:00  -554   339  649     3
15 549908 4789631       10  1/30/2008  9:00   -84    75  112     3
16 550378 4789367       10  1/30/2008 17:00   -48    62   78     3
17 550414 4789354       10  1/31/2008  1:00  -579   153  598     3
18 549883 4789445       10  1/31/2008  9:00  -236   198  308     3
19 550226 4789490       10  1/31/2008 17:00  -174   203  267     3
20 550288 4789495       10   2/1/2008  1:00    NA    NA   NA    NA

Also I think you made a mistake above at xdist16 because for xlocline17 - xlocline16 + xdistline15 = 550414 - 550378 + (-84) = -48 and not 657 as you specified. Unless I missed something at your formula.

Hope this helps!

LyzandeR
  • 37,047
  • 12
  • 77
  • 87
  • Impressive! Thank you! Because there are multiple individuals, I will need to insert a 'for i in animal id' loop prior to the existing loop, correct? – odocoileus Nov 13 '14 at 17:28
  • I added for(i in unique(animal id)) to run a loop with the above code through each individual animal and it doesn't seem to work. It is a concern because if last location of animal A is within 800m of the first location of animal B, the NSD formula will continue to operate. Do you have any idea how I could avoid this issue? Much thanks. – odocoileus Jan 20 '15 at 18:09
  • You should probably make a function for my above code and then create a for-loop to iterate through the whole dataset. Another way would be to use `group_by` from `dplyr` to do that which essentially, would split the table in groups according to animal ID. I cannot do anything here atm. I suggest you post a new question and add another representative example. – LyzandeR Jan 20 '15 at 18:29
  • Another way is to run a loop for each subset of your dataframe according to the animal id. something like `for (i in unique(df$animalid)) {mysubset <- df[ ,df$animalid==1]}` and then the rest of the code for on the subset. – LyzandeR Jan 20 '15 at 18:32
  • Sorry wrote the above too hastily I think. It should be: `for (i in unique(df$animalid)) {mysubset <- df[df$animalid==i, ] }`. Try this one. I am pretty sure it should work. Otherwise please post a different question and I am glad to help. It is difficult to test otherwise... – LyzandeR Jan 20 '15 at 18:40
  • Thank you for the tips - unfortunately, it didn't work. I will post as a new questions shortly. – odocoileus Jan 20 '15 at 19:26