R 如何计算两个位置之间的距离和时间

R 如何计算两个位置之间的距离和时间,r,datetime,distance,timestep,R,Datetime,Distance,Timestep,下面是一些数据的示例 Tag.ID TimeStep.coa Latitude.coa Longitude.coa <chr> <dttm> <dbl> <dbl> 1 1657 2017-08-17 12:00:00 72.4 -81.1 2 1657 2017-08-17 18:00:00 72.3

下面是一些数据的示例

  Tag.ID TimeStep.coa        Latitude.coa Longitude.coa
   <chr>  <dttm>                     <dbl>         <dbl>
 1 1657   2017-08-17 12:00:00         72.4         -81.1
 2 1657   2017-08-17 18:00:00         72.3         -81.1
 3 1658   2017-08-14 18:00:00         72.3         -81.2
 4 1658   2017-08-15 00:00:00         72.3         -81.3
 5 1659   2017-08-14 18:00:00         72.3         -81.1
 6 1659   2017-08-15 00:00:00         72.3         -81.2
 7 1660   2017-08-20 18:00:00         72.3         -81.1
 8 1660   2017-08-21 00:00:00         72.3         -81.2
 9 1660   2017-08-21 06:00:00         72.3         -81.2
10 1660   2017-08-21 12:00:00         72.3         -81.3
11 1661   2017-08-28 12:00:00         72.4         -81.1
12 1661   2017-08-28 18:00:00         72.3         -81.1
13 1661   2017-08-29 06:00:00         72.3         -81.2
14 1661   2017-08-29 12:00:00         72.3         -81.2
15 1661   2017-08-30 06:00:00         72.3         -81.2
16 1661   2017-08-30 18:00:00         72.3         -81.2
17 1661   2017-08-31 00:00:00         72.3         -81.2
18 1661   2017-08-31 06:00:00         72.3         -81.2
19 1661   2017-08-31 12:00:00         72.3         -81.2
20 1661   2017-08-31 18:00:00         72.4         -81.1
这将计算lat/lon坐标之间的直线距离。 我最终想要一个包含四列Tag.ID、Timestep1、Timestep2和distance的数据帧。下面是一个例子:

Tag.ID   Timestep1            Timestep2               Distance
1657     2017-08-17 12:00:00  2017-08-17 18:00:00     ComputeDistance(72.4,72.3,-81.1,-81.1)
1658     2017-08-14 18:00:00  2017-08-15 00:00:00   ComputeDistance(72.3,72.3,-81.2,-81.3)
1659     2017-08-14 18:00:00  2017-08-15 00:00:00  ComputeDistance(72.3,72.3,-81.1,-81.2)
1660    2017-08-20 18:00:00   2017-08-21 00:00:00  ComputeDistance(72.3,72.3,-81.1,-81.2)
1660   2017-08-21 00:00:00   2017-08-21 06:00:00  ComputeDistance(72.3,72.3,=81.1,-81.2
等等

编辑: 这是我使用的代码(谢谢AntoniosK)。COASpeeds2与上述样本df完全相同:

test <- COASpeeds2 %>%
  group_by(Tag.ID) %>%
  mutate(Timestep1 = TimeStep.coa,
         Timestep2 = lead(TimeStep.coa),
         Distance = ComputeDistance(Latitude.coa, lead(Latitude.coa),
                                    Longitude.coa, lead(Longitude.coa))) %>%

  ungroup() %>%
  na.omit() %>%
  select(Tag.ID, Timestep1, Timestep2, Distance)
test%
分组依据(标记ID)%>%
突变(Timestep1=TimeStep.coa,
Timestep2=领先(TimeStep.coa),
距离=计算距离(Latitude.coa,lead(Latitude.coa),
经度.coa,导程(经度.coa))%>%
解组()%>%
na.省略()%>%
选择(Tag.ID、Timestep1、Timestep2、距离)
这是我得到的df

   Tag.ID Timestep1           Timestep2           Distance
   <fct>  <dttm>              <dttm>                 <dbl>
 1 1657   2017-08-17 12:00:00 2017-08-17 18:00:00    2.76 
 2 1657   2017-08-17 18:00:00 2017-08-14 18:00:00    1.40 
 3 1658   2017-08-14 18:00:00 2017-08-15 00:00:00    6.51 
 4 1658   2017-08-15 00:00:00 2017-08-14 18:00:00   10.5  
 5 1659   2017-08-14 18:00:00 2017-08-15 00:00:00    7.51 
 6 1659   2017-08-15 00:00:00 2017-08-20 18:00:00    7.55 
 7 1660   2017-08-20 18:00:00 2017-08-21 00:00:00    3.69 
 8 1660   2017-08-21 00:00:00 2017-08-21 06:00:00    4.32 
 9 1660   2017-08-21 06:00:00 2017-08-21 12:00:00    3.26 
10 1660   2017-08-21 12:00:00 2017-08-28 12:00:00   10.5  
11 1661   2017-08-28 12:00:00 2017-08-28 18:00:00    1.60 
12 1661   2017-08-28 18:00:00 2017-08-29 06:00:00    1.94 
13 1661   2017-08-29 06:00:00 2017-08-29 12:00:00    5.22 
14 1661   2017-08-29 12:00:00 2017-08-30 06:00:00    0.759
15 1661   2017-08-30 06:00:00 2017-08-30 18:00:00    1.94 
16 1661   2017-08-30 18:00:00 2017-08-31 00:00:00    0.342
17 1661   2017-08-31 00:00:00 2017-08-31 06:00:00    0.281
18 1661   2017-08-31 06:00:00 2017-08-31 12:00:00    4.21 
19 1661   2017-08-31 12:00:00 2017-08-31 18:00:00    8.77 
Tag.ID Timestep1 Timestep2距离
1 1657   2017-08-17 12:00:00 2017-08-17 18:00:00    2.76 
2 1657   2017-08-17 18:00:00 2017-08-14 18:00:00    1.40 
3 1658   2017-08-14 18:00:00 2017-08-15 00:00:00    6.51 
4 1658   2017-08-15 00:00:00 2017-08-14 18:00:00   10.5  
5 1659   2017-08-14 18:00:00 2017-08-15 00:00:00    7.51 
6 1659   2017-08-15 00:00:00 2017-08-20 18:00:00    7.55 
7 1660   2017-08-20 18:00:00 2017-08-21 00:00:00    3.69 
8 1660   2017-08-21 00:00:00 2017-08-21 06:00:00    4.32 
9 1660   2017-08-21 06:00:00 2017-08-21 12:00:00    3.26 
10 1660   2017-08-21 12:00:00 2017-08-28 12:00:00   10.5  
11 1661   2017-08-28 12:00:00 2017-08-28 18:00:00    1.60 
12 1661   2017-08-28 18:00:00 2017-08-29 06:00:00    1.94 
13 1661   2017-08-29 06:00:00 2017-08-29 12:00:00    5.22 
14 1661   2017-08-29 12:00:00 2017-08-30 06:00:00    0.759
15 1661   2017-08-30 06:00:00 2017-08-30 18:00:00    1.94 
16 1661   2017-08-30 18:00:00 2017-08-31 00:00:00    0.342
17 1661   2017-08-31 00:00:00 2017-08-31 06:00:00    0.281
18 1661   2017-08-31 06:00:00 2017-08-31 12:00:00    4.21 
19 1661   2017-08-31 12:00:00 2017-08-31 18:00:00    8.77 
因此,您可以得到以下结果:

# # A tibble: 6 x 4
#     Tag.ID Timestep1           Timestep2             Distance
#     <int> <fct>               <fct>                    <dbl>
# 1   1657 2017-08-17_12:00:00 2017-08-17_18:00:00 11.1      
# 2   1658 2017-08-14_18:00:00 2017-08-15_00:00:00  3.38     
# 3   1659 2017-08-14_18:00:00 2017-08-15_00:00:00  3.38     
# 4   1660 2017-08-20_18:00:00 2017-08-21_00:00:00  3.38     
# 5   1660 2017-08-21_00:00:00 2017-08-21_06:00:00  0.0000949
# 6   1660 2017-08-21_06:00:00 2017-08-21_12:00:00  3.38 
##tible:6 x 4
#Tag.ID Timestep1 Timestep2距离
#                                         
# 1   1657 2017-08-17_12:00:00 2017-08-17_18:00:00 11.1      
# 2   1658 2017-08-14_18:00:00 2017-08-15_00:00:00  3.38     
# 3   1659 2017-08-14_18:00:00 2017-08-15_00:00:00  3.38     
# 4   1660 2017-08-20_18:00:00 2017-08-21_00:00:00  3.38     
# 5   1660 2017-08-21_00:00:00 2017-08-21_06:00:00  0.0000949
# 6   1660 2017-08-21_06:00:00 2017-08-21_12:00:00  3.38 

假设起点和终点是有序的,并且有一对匹配的。
这是另一个选择:

#identify the start and end of each trip
df$leg<-rep(c("Start", "End"), nrow(df)/2)
#label each trip
df$trip <- rep(1:(nrow(df)/2), each=2)

#change the shape
library(tidyr)
output<-pivot_wider(df, id_cols = c(Tag.ID, trip),
            names_from = leg, 
            values_from = c(TimeStep.coa, Latitude.coa, Longitude.coa))

#calcuate distance (use your package of choice)
library(geosphere)
output$distance<-distGeo(output[ ,c("Longitude.coa_Start", "Latitude.coa_Start")], 
                         output[ ,c("Longitude.coa_End", "Latitude.coa_End")])

# #remove undesired columns
# output <- output[, -c(5, 6, 7, 8)]
output


> output[, -c(5, 6, 7, 8)]
# A tibble: 10 x 5
   Tag.ID  trip TimeStep.coa_Start  TimeStep.coa_End    distance
    <int> <int> <fct>               <fct>                  <dbl>
 1   1657     1 2017-08-17 12:00:00 2017-08-17 18:00:00   11159.
 2   1658     2 2017-08-14 18:00:00 2017-08-15 00:00:00    3395.
 3   1659     3 2017-08-14 18:00:00 2017-08-15 00:00:00    3395.
 4   1660     4 2017-08-20 18:00:00 2017-08-21 00:00:00    3395.
 5   1660     5 2017-08-21 06:00:00 2017-08-21 12:00:00    3395.
 6   1661     6 2017-08-28 12:00:00 2017-08-28 18:00:00   11159.
 7   1661     7 2017-08-29 06:00:00 2017-08-29 12:00:00       0 
 8   1661     8 2017-08-30 06:00:00 2017-08-30 18:00:00       0 
 9   1661     9 2017-08-31 00:00:00 2017-08-31 06:00:00       0 
10   1661    10 2017-08-31 12:00:00 2017-08-31 18:00:00   11661.
#识别每次行程的开始和结束

df$leg您可以使用
geosphere::distGeo
by
方法

library(geosphere)
do.call(rbind.data.frame, by(dat, dat$Tag.ID, function(s) {
  t.diff <- (s$TimeStep.coa[length(s$TimeStep.coa)] - s$TimeStep.coa[1])
  d.diff <- sum(mapply(function(x, y)
    distGeo(s[x, 3:4], s[y, 3:4]), x=1:(nrow(s)-1), y=2:nrow(s)))/1e3
  `colnames<-`(cbind(t.diff, d.diff), c("hours", "km"))
}))
#      hours        km
# 1657  6.00  1.727882
# 1658  6.00 11.166785
# 1659  6.00 11.166726
# 1660 18.00 22.333511
# 1661  3.25 24.192753
库(geosphere)
do.call(rbind.data.frame,by(dat,dat$Tag.ID,函数){

t、 区分超过2行的
Tag.ID
会发生什么情况?@AntoniosK编辑了这篇文章以回答您的问题您是否尝试安装库(geosphere)使用它,你可以做很多事情,比如lat/lonYes之间的距离。我想要的是按TagID对_进行分组。但是,我不想要第一行和最后一行,而是第一行和第二行,第二行和第三行,第三行和第四行等等。有意义吗?这太接近了!知道为什么它可能会给我两行ID,而应该有一行吗?请看编辑…算出了,我想出来了nk有两个问题。第一,我以前安装过plyr,所以其中一些函数覆盖了dplyr函数。此外,我认为我的数据帧的类不同,这会干扰操作
#identify the start and end of each trip
df$leg<-rep(c("Start", "End"), nrow(df)/2)
#label each trip
df$trip <- rep(1:(nrow(df)/2), each=2)

#change the shape
library(tidyr)
output<-pivot_wider(df, id_cols = c(Tag.ID, trip),
            names_from = leg, 
            values_from = c(TimeStep.coa, Latitude.coa, Longitude.coa))

#calcuate distance (use your package of choice)
library(geosphere)
output$distance<-distGeo(output[ ,c("Longitude.coa_Start", "Latitude.coa_Start")], 
                         output[ ,c("Longitude.coa_End", "Latitude.coa_End")])

# #remove undesired columns
# output <- output[, -c(5, 6, 7, 8)]
output


> output[, -c(5, 6, 7, 8)]
# A tibble: 10 x 5
   Tag.ID  trip TimeStep.coa_Start  TimeStep.coa_End    distance
    <int> <int> <fct>               <fct>                  <dbl>
 1   1657     1 2017-08-17 12:00:00 2017-08-17 18:00:00   11159.
 2   1658     2 2017-08-14 18:00:00 2017-08-15 00:00:00    3395.
 3   1659     3 2017-08-14 18:00:00 2017-08-15 00:00:00    3395.
 4   1660     4 2017-08-20 18:00:00 2017-08-21 00:00:00    3395.
 5   1660     5 2017-08-21 06:00:00 2017-08-21 12:00:00    3395.
 6   1661     6 2017-08-28 12:00:00 2017-08-28 18:00:00   11159.
 7   1661     7 2017-08-29 06:00:00 2017-08-29 12:00:00       0 
 8   1661     8 2017-08-30 06:00:00 2017-08-30 18:00:00       0 
 9   1661     9 2017-08-31 00:00:00 2017-08-31 06:00:00       0 
10   1661    10 2017-08-31 12:00:00 2017-08-31 18:00:00   11661.
library(geosphere)
do.call(rbind.data.frame, by(dat, dat$Tag.ID, function(s) {
  t.diff <- (s$TimeStep.coa[length(s$TimeStep.coa)] - s$TimeStep.coa[1])
  d.diff <- sum(mapply(function(x, y)
    distGeo(s[x, 3:4], s[y, 3:4]), x=1:(nrow(s)-1), y=2:nrow(s)))/1e3
  `colnames<-`(cbind(t.diff, d.diff), c("hours", "km"))
}))
#      hours        km
# 1657  6.00  1.727882
# 1658  6.00 11.166785
# 1659  6.00 11.166726
# 1660 18.00 22.333511
# 1661  3.25 24.192753
dat <- structure(list(Tag.ID = c(1657L, 1657L, 1658L, 1658L, 1659L, 
1659L, 1660L, 1660L, 1660L, 1660L, 1661L, 1661L, 1661L, 1661L, 
1661L, 1661L, 1661L, 1661L, 1661L, 1661L), TimeStep.coa = structure(c(1502964000, 
1502985600, 1502726400, 1502748000, 1502726400, 1502748000, 1503244800, 
1503266400, 1503288000, 1503309600, 1503914400, 1503936000, 1503979200, 
1504000800, 1504065600, 1504108800, 1504130400, 1504152000, 1504173600, 
1504195200), class = c("POSIXct", "POSIXt"), tzone = ""), Latitude.coa = c(72.4, 
72.3, 72.3, 72.3, 72.3, 72.3, 72.3, 72.3, 72.3, 72.3, 72.4, 72.3, 
72.3, 72.3, 72.3, 72.3, 72.3, 72.3, 72.3, 72.4), Longitude.coa = c(-81.1, 
-81.1, -81.2, -81.3, -81.1, -81.2, -81.1, -81.2, -81.2, -81.3, 
-81.1, -81.1, -81.2, -81.2, -81.2, -81.2, -81.2, -81.2, -81.2, 
-81.1)), row.names = c(NA, -20L), class = "data.frame")