简体   繁体   English

计算不同时间点动物之间的距离

[英]Calculate the distance between animals at different time points

I have the GPS coordinates in Easting & Northing for a year for three animals.我在 Easting & Northing 的 GPS 坐标为三只动物一年。 I want to calculate the distance between each of the animals at each of the time points.我想计算每个时间点上每只动物之间的距离。

I have no idea how to do this and any help would be very appreciated.我不知道如何做到这一点,任何帮助将不胜感激。

I've included an example of my data in case that helps.我已经包含了我的数据示例,以防万一。

     ID     GPS.E  GPS.S  Date       Time
1  Animal 1 417547 393907 2017-01-01 06:19
2  Animal 1 417769 395000 2017-01-01 16:34
3  Animal 1 418418 394985 2017-01-02 08:18
4  Animal 1 419448 395405 2017-01-02 15:57
5  Animal 1 418249 396145 2017-01-03 07:24
6  Animal 1 417399 396238 2017-01-03 17:44
7  Animal 1 417320 396119 2017-01-04 06:33
8  Animal 1 417770 396080 2017-01-04 17:01
9  Animal 1 417232 396812 2017-01-05 08:43
10 Animal 1 417716 396745 2017-01-05 16:43
11 Animal 2 416571 396099 2017-01-01 06:24
12 Animal 2 416423 395996 2017-01-01 16:15
13 Animal 2 416184 395916 2017-01-02 08:28
14 Animal 2 416002 395858 2017-01-02 15:34
15 Animal 2 415454 395993 2017-01-03 07:14
16 Animal 2 415450 397175 2017-01-03 17:27
17 Animal 2 415781 396949 2017-01-04 06:12
18 Animal 2 415702 396949 2017-01-04 17:23
19 Animal 2 415017 397185 2017-01-05 08:12
20 Animal 2 414516 396990 2017-01-05 16:18
21 Animal 3 418971 394300 2017-01-01 05:59
22 Animal 3 418275 394558 2017-01-01 16:45
23 Animal 3 419881 394940 2017-01-02 08:20
24 Animal 3 420304 394669 2017-01-02 15:25
25 Animal 3 419585 394825 2017-01-03 07:20
26 Animal 3 421528 396153 2017-01-03 17:03
27 Animal 3 420045 396510 2017-01-04 06:27
28 Animal 3 419636 396349 2017-01-04 17:17
29 Animal 3 419499 396212 2017-01-05 08:22
30 Animal 3 420515 395898 2017-01-05 16:14 ````


The desired output is 

ID      Distance to Animal 1  Distance to Animal 2  Distance to Animal 3 
Animal 1
Animal 1
Animal 1
Animal 1
Animal 1
Animal 1
Animal 1
Animal 1
Animal 1
Animal 1
Animal 2
Animal 2
Animal 2
Animal 2
etc. 


   

Looks like a simple question, but surprisingly hard to tackle (for me at least)..看起来像一个简单的问题,但出奇地难以解决(至少对我来说)..

Please check some answers by hand, to make sure i understood the coordinates correctly.请手动检查一些答案,以确保我正确理解坐标。 Distance is (should be) in metres..距离(应该)以米为单位。

library( data.table )
library( sf )
library( geosphere )
library( tidyverse )

#sample data
DT <- data.table::fread("rowid ID     GPS.E  GPS.S  Date       Time
1  Animal1 417547 393907 2017-01-01 06:19
2  Animal1 417769 395000 2017-01-01 16:34
3  Animal1 418418 394985 2017-01-02 08:18
4  Animal1 419448 395405 2017-01-02 15:57
5  Animal1 418249 396145 2017-01-03 07:24
6  Animal1 417399 396238 2017-01-03 17:44
7  Animal1 417320 396119 2017-01-04 06:33
8  Animal1 417770 396080 2017-01-04 17:01
9  Animal1 417232 396812 2017-01-05 08:43
10 Animal1 417716 396745 2017-01-05 16:43
11 Animal2 416571 396099 2017-01-01 06:24
12 Animal2 416423 395996 2017-01-01 16:15
13 Animal2 416184 395916 2017-01-02 08:28
14 Animal2 416002 395858 2017-01-02 15:34
15 Animal2 415454 395993 2017-01-03 07:14
16 Animal2 415450 397175 2017-01-03 17:27
17 Animal2 415781 396949 2017-01-04 06:12
18 Animal2 415702 396949 2017-01-04 17:23
19 Animal2 415017 397185 2017-01-05 08:12
20 Animal2 414516 396990 2017-01-05 16:18
21 Animal3 418971 394300 2017-01-01 05:59
22 Animal3 418275 394558 2017-01-01 16:45
23 Animal3 419881 394940 2017-01-02 08:20
24 Animal3 420304 394669 2017-01-02 15:25
25 Animal3 419585 394825 2017-01-03 07:20
26 Animal3 421528 396153 2017-01-03 17:03
27 Animal3 420045 396510 2017-01-04 06:27
28 Animal3 419636 396349 2017-01-04 17:17
29 Animal3 419499 396212 2017-01-05 08:22
30 Animal3 420515 395898 2017-01-05 16:14")

DT[, datetime := as.POSIXct( paste(Date, Time ), format = "%Y-%m-%d %H:%M" ) ]

#convert cvoordinates to 'normal' wgs84 lon/lat
library( sf )
DT[ , c("lon", "lat") := DT %>% 
      sf::st_as_sf( coords = c("GPS.S", "GPS.E"), crs = 32629 ) %>% 
      sf::st_transform( 4326 ) %>% sf::st_coordinates() %>% data.table::as.data.table() ][]


#split by animal
L <- split( DT, by = "ID" )
#update to get closest rownumbers
lapply( L, function(x) {
  lapply( L, function(y) {
    #update x with the rowid of the nearest timestamp in y
    x[, unique(y$ID) := y[x, x.rowid, roll = "nearest", on = .(datetime)] ]
  })
})

#bind together again
DT <- data.table::rbindlist( L )

#melt to long format
DT.melt <- data.table::melt(DT, 
                            measure.vars = patterns("^Animal[0-9]+"), 
                            variable.name = "ID2", 
                            variable.factor = FALSE,
                            value.name = "rowid2" )
#join in the coordinates of the ID2-animal
DT.melt[ DT, `:=`( lon2 = i.lon, lat2 = i.lat ), on = .(rowid2 = rowid) ][]
#calculate the distance between c(lon, lat) and c(lon2, lat2)
# I do no know the data.table approach here, so a small switch to the tidyverse
DT.melt <- DT.melt %>%
  dplyr::mutate( distance = purrr::pmap( 
    list( a = lon, 
          b = lat, 
          x = lon2,
          y = lat2 ), 
    ~ round( geosphere::distHaversine( c(..1, ..2), c(..3, ..4) ) ) ) )
#now, cast to wide again
dcast( DT.melt, rowid + ID + GPS.E + GPS.S + Date + Time ~ ID2, value.var = "distance" )


#output
#     rowid      ID  GPS.E  GPS.S       Date  Time Animal1 Animal2 Animal3
#  1:     1 Animal1 417547 393907 2017-01-01 06:19       0    2403    1487
#  2:     2 Animal1 417769 395000 2017-01-01 16:34       0    1682     675
#  3:     3 Animal1 418418 394985 2017-01-02 08:18       0    2435    1474
#  4:     4 Animal1 419448 395405 2017-01-02 15:57       0    3499    1134
#  5:     5 Animal1 418249 396145 2017-01-03 07:24       0    2819    1885
#  6:     6 Animal1 417399 396238 2017-01-03 17:44       0    2175    4159
#  7:     7 Animal1 417320 396119 2017-01-04 06:33       0    1758    2772
#  8:     8 Animal1 417770 396080 2017-01-04 17:01       0    2257    1898
#  9:     9 Animal1 417232 396812 2017-01-05 08:43       0    2261    2360
# 10:    10 Animal1 417716 396745 2017-01-05 16:43       0    3232    2943
# 11:    11 Animal2 416571 396099 2017-01-01 06:24    2403       0    3013
# 12:    12 Animal2 416423 395996 2017-01-01 16:15    1682       0    2355
# 13:    13 Animal2 416184 395916 2017-01-02 08:28    2435       0    3849
# 14:    14 Animal2 416002 395858 2017-01-02 15:34    3499       0    4492
# 15:    15 Animal2 415454 395993 2017-01-03 07:14    2819       0    4321
# 16:    16 Animal2 415450 397175 2017-01-03 17:27    2175       0    6205
# 17:    17 Animal2 415781 396949 2017-01-04 06:12    1758       0    4316
# 18:    18 Animal2 415702 396949 2017-01-04 17:23    2257       0    4007
# 19:    19 Animal2 415017 397185 2017-01-05 08:12    2261       0    4617
# 20:    20 Animal2 414516 396990 2017-01-05 16:18    3232       0    6139
# 21:    21 Animal3 418971 394300 2017-01-01 05:59    1487    3013       0
# 22:    22 Animal3 418275 394558 2017-01-01 16:45     675    2355       0
# 23:    23 Animal3 419881 394940 2017-01-02 08:20    1474    3849       0
# 24:    24 Animal3 420304 394669 2017-01-02 15:25    1134    4492       0
# 25:    25 Animal3 419585 394825 2017-01-03 07:20    1885    4321       0
# 26:    26 Animal3 421528 396153 2017-01-03 17:03    4159    6205       0
# 27:    27 Animal3 420045 396510 2017-01-04 06:27    2772    4316       0
# 28:    28 Animal3 419636 396349 2017-01-04 17:17    1898    4007       0
# 29:    29 Animal3 419499 396212 2017-01-05 08:22    2360    4617       0
# 30:    30 Animal3 420515 395898 2017-01-05 16:14    2943    6139       0
#     rowid      ID  GPS.E  GPS.S       Date  Time Animal1 Animal2 Animal3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM