Search code examples
rloopscenterspatial

R: How to find spatial points within a certain radius of a trajectory and to ensure that they are consecutive


I'm struggling with a space-time problem. Help is very much appreciated! Here's first what I'm looking for:

I've got a dataframe with fixes of roe deer datapoints (x,y-coordinates) taken in a irregular approximatly five minute interval.

  1. I want to find all fixes within a certain radius (let's say 15 Meters) of the acutall position of the roe deer, with the condition that they are consecutiv for about 30 Minutes (so six fixes). Oviously the number of fixes can vary along the trajectory. I want to write down the number of fixes into a new column and want to mark in another column (0=no,1=yes), if the condition is met.

  2. If the conditions are met, I would like to calculate the center of gravity (in x,y-coordinates) of said pointcloud and write it to this or another dataframe.

According to another users question (Listing number of obervations by location) I was able to find the fixes within the radius, but i couldn't figure a way how to ensure that they are consecutive

Here's some rows of my dataframe (in realty there's more than 10000 rows, because i subsetted this data.frame the ID's are not starting with one):

    FID  No CollarID       Date     Time Latitude__ Longitude_ Height__m_  DOP     FixType
1    0 667     7024 2013-10-22 06:01:49   47.26859   8.570701     609.94 10.6      GPS-3D
2    1 668     7024 2013-10-22 06:06:04   47.26861   8.570634     612.31 10.4      GPS-3D
3    2 669     7024 2013-10-22 06:11:07   47.26871   8.570402     609.43  9.8      GPS-3D
4    3 670     7024 2013-10-22 06:16:14   47.26857   8.570796     665.40  4.4 val. GPS-3D
5    4 671     7024 2013-10-22 06:20:36   47.26855   8.570582     653.65  4.6 val. GPS-3D
6    5 672     7024 2013-10-22 06:25:50   47.26850   8.570834     659.03  4.8 val. GPS-3D
7    6 673     7024 2013-10-23 06:00:53   47.27017   8.569882     654.86  3.6 val. GPS-3D
8    7 700     7024 2013-10-26 12:00:18   47.26904   8.569596     651.88  3.8 val. GPS-3D
9    8 701     7024 2013-10-26 12:05:41   47.26899   8.569640     652.76  3.8 val. GPS-3D
10   9 702     7024 2013-10-26 12:10:40   47.26898   8.569534     650.42  4.6 val. GPS-3D
11  10 703     7024 2013-10-26 12:16:17   47.26896   8.569606     653.77 11.4      GPS-3D
12  11 704     7024 2013-10-26 12:20:18   47.26903   8.569792     702.49  9.8 val. GPS-3D
13  12 705     7024 2013-10-26 12:25:47   47.26901   8.569579     670.12  2.4 val. GPS-3D
14  13 706     7024 2013-10-26 12:30:18   47.26900   8.569477     685.65  2.0 val. GPS-3D
15  14 707     7024 2013-10-26 12:35:23   47.26885   8.569400     685.15  6.2 val. GPS-3D
   Temp___C_        X        Y   ID Trajectory   distance       speed     timelag timevalid
1         19 685667.7 235916.0 RE01       RE01   5.420858 0.021258268    4.250000         1
2         20 685662.6 235917.8 RE01       RE01  21.276251 0.070218649    5.050000         1
3         20 685644.9 235929.5 RE01       RE01  34.070730 0.110979577    5.116667         1
4         20 685675.0 235913.5 RE01       RE01  16.335573 0.062349516    4.366667         1
5         20 685658.8 235911.3 RE01       RE01  19.896906 0.063365941    5.233333         1
6         20 685677.9 235905.7 RE01       RE01 199.248728 0.002346781 1415.050000         0
7         22 685603.2 236090.4 RE01       RE01 126.831124 0.000451734 4679.416667         0
8         22 685583.4 235965.1 RE01       RE01   6.330467 0.019598970    5.383333         1
9         22 685586.8 235959.8 RE01       RE01   8.270701 0.027661208    4.983333         1
10        23 685578.8 235957.8 RE01       RE01   5.888147 0.017472246    5.616667         1
11        22 685584.3 235955.7 RE01       RE01  16.040998 0.066560158    4.016667         1
12        23 685598.3 235963.6 RE01       RE01  16.205330 0.049256322    5.483333         1
13        23 685582.2 235961.6 RE01       RE01   7.742184 0.028568946    4.516667         1
14        23 685574.5 235960.9 RE01       RE01  18.129019 0.059439406    5.083333         1
15        23 685568.8 235943.7 RE01       RE01  15.760165 0.051672673    5.083333         1
    Date_text Time_text            DateTime Flucht FluchtALL
1  22.10.2013  06:01:49 22.10.2013 06:01:49      0         0
2  22.10.2013  06:06:04 22.10.2013 06:06:04      0         0
3  22.10.2013  06:11:07 22.10.2013 06:11:07      0         0
4  22.10.2013  06:16:14 22.10.2013 06:16:14      0         0
5  22.10.2013  06:20:36 22.10.2013 06:20:36      0         0
6  22.10.2013  06:25:50 22.10.2013 06:25:50      0         0
7  23.10.2013  06:00:53 23.10.2013 06:00:53      0         0
8  26.10.2013  12:00:18 26.10.2013 12:00:18      0         0
9  26.10.2013  12:05:41 26.10.2013 12:05:41      0         0
10 26.10.2013  12:10:40 26.10.2013 12:10:40      0         0
11 26.10.2013  12:16:17 26.10.2013 12:16:17      0         0
12 26.10.2013  12:20:18 26.10.2013 12:20:18      0         0
13 26.10.2013  12:25:47 26.10.2013 12:25:47      0         0
14 26.10.2013  12:30:18 26.10.2013 12:30:18      0         0
15 26.10.2013  12:35:23 26.10.2013 12:35:23      0         0

and here's the code i've got so far:

for (i in seq(nrow(df)))
{
  # circle's centre
  xcentre <- df[i,'X']
  ycentre <- df[i,'Y']

  # checking how many fixes lie within 15 m of the above centre, noofcloserest column will contain this value
  df[i,'noofclosepoints'] <- sum(
    (df[,'X'] - xcentre)^2 + 
      (df[,'Y'] - ycentre)^2 
    <= 15^2
  ) - 1

  cat(i,': ')
  # this prints the true/false vector for which row is within the radius, and which row isn't
  cat((df[,'X'] - xcentre)^2 + 
        (df[,'Y'] - ycentre)^2 
      <= 15^2)

  cat('\n')

}

I tried to test the consecutive-condition on the TRUE/FALSE List from cat(), but i couldn't access the results to process them any further.

I know this is a mile long question, I would be very glad if someone could help me with this or part of this problem. I will be thankful till the end of my life :). Btw: you may have noticed, that I'm an unfortunate R beginner. Many thanks!

Here's how


Solution

  • You can apply a rolling function to your time series for a window of 6.

    library(xts)
    ## You read you time serie using the handy `read.zoo`
    ## Note the use of the index here
    dx <- 
    read.zoo(text="Date     Time  DOP        X        Y noofclosepoints
    4705 09.07.2014 11:05:33  3.4 686926.8 231039.3              14
    4706 09.07.2014 11:10:53  3.2 686930.5 231042.5              14
    4707 09.07.2014 11:16:29 15.8 686935.2 231035.5              14
    4708 09.07.2014 11:20:08  5.2 686932.9 231035.6              14
    4709 09.07.2014 11:25:17  4.8 686933.8 231038.6              14
    4710 09.07.2014 11:30:16  2.2 686938.0 231037.0              15
    4711 09.07.2014 11:35:13  2.0 686930.9 231035.8              14
    4712 09.07.2014 11:40:09  2.0 686930.6 231035.7              14
    4713 09.07.2014 11:45:25  3.4 686907.2 231046.8               0
    4714 09.07.2014 11:50:25  3.2 686936.1 231037.1              14",
             index = 1:2,format="%d.%m.%Y %H:%M:%S",tz="")
    
    
    ## You apply your rolling to all columns 
    ## for each window you compute the distance between the current 
    ## point and others , then you return the number of points within the radius
    as.xts(rollapplyr(dx,7,function(x) {
      curr <- tail(x,1)
      others <- head(x,-1)
      dist <- sqrt((others[,"X"]-curr[,"X"])^2 + (others[,"Y"]-curr[,"Y"])^2 )
      sum(dist<15)
    
    },by.column=FALSE))
    
    #                     [,1]
    # 2014-07-09 11:35:13    6
    # 2014-07-09 11:40:09    6
    # 2014-07-09 11:45:25    0
    # 2014-07-09 11:50:25    5