计算不同时间点动物之间的距离 [英] Calculate the distance between animals at different time points

查看:37
本文介绍了计算不同时间点动物之间的距离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Easting&北上一年的三只动物.我想计算每个时间点每个动物之间的距离.

I have the GPS coordinates in Easting & Northing for a year for three animals. 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

这篇关于计算不同时间点动物之间的距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆