使用距离(geosphere)和difftime计算lon / lat和时间戳的平均速度

时间:2017-06-07 12:48:19

标签: r timestamp rows geospatial distance

我试图使用geosphere的distm函数找出两个连续实例(行)之间的半径距离。最后,我想用米的距离除以秒的时差来计算平均速度。

这就是我用秒计算时差的方法

<ant:javadoc doclet="com.tarsec.javadoc.pdfdoclet.PDFDoclet"
        docletpath="./jar/pdfdoclet-1.0.0-all.jar"
        packagenames="com.jlaby.*"
        overview="./example/laby/overview_laby.html"
        additionalparam="-pdf ./example/results/laby.pdf -config ./example/laby/config_laby.properties"
        private="no"
        sourcepath="./example/laby" >
</ant:javadoc>

之前已经询问similar question并且答案确实有效但我需要按ID索引,以便每个新ID都以NA开头。我想创建一个名为df$Timediff_secs <- with(df, difftime(Timestamp, ave(Timestamp, ID, FUN=lag), units='secs')) 的新列。

这需要进行编辑,以便按ID进行索引,以便第一行为NA(因为要计算的距离没有差异)

df$Distance

以下是我从链接中复制的一些示例数据

library(geosphere)
metersPerMile <- 1609.34
pts <- df1[c("lon", "lat")]

## Pass in two derived data.frames that are lagged by one point
segDists <- distVincentyEllipsoid(p1 = pts[-nrow(df),], 
                                  p2 = pts[-1,])
sum(segDists)/metersPerMile
# [1] 1013.919

感觉就像我尝试了一切,非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } // OR func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } dplyr::lag和分组对此非常方便,但可以在data.table::shiftc(NA, variable[-length(variable)])之类的基础上手动完成:

aggregate

由于data.frame已经分组,因此聚合只需求求和:

library(dplyr)

df <- structure(list(Timestamp = structure(c(1352704121, 1352704181, 1352704241, 1352708321, 1352708381, 1352708441), 
                                           class = c("POSIXct", "POSIXt"), tzone = ""), 
                     ID = c(1L, 1L, 1L, 2L, 2L, 2L), 
                     lat = c(76.57169, 76.44325, 76.90897, 76.11152, 76.29013, 76.15544), 
                     lon = c(-110.807, -110.7525, -110.8613, -110.2037, -110.3838, -110.4506)), 
                class = "data.frame", .Names = c("Timestamp", "ID", "lat", "lon"), row.names = c(NA, -6L))

df <- df %>% 
    group_by(ID) %>%
    mutate(dist_m = geosphere::distVincentyEllipsoid(cbind(lon, lat), 
                                                     cbind(lag(lon), lag(lat))), 
           time_s = difftime(Timestamp, lag(Timestamp), units = 'secs'), 
           speed_m_per_s = dist_m / as.integer(time_s))

df
#> # A tibble: 6 x 7
#> # Groups:   ID [2]
#>             Timestamp    ID      lat       lon   dist_m  time_s speed_m_per_s
#>                <dttm> <int>    <dbl>     <dbl>    <dbl>  <time>         <dbl>
#> 1 2012-11-12 02:08:41     1 76.57169 -110.8070       NA NA secs            NA
#> 2 2012-11-12 02:09:41     1 76.44325 -110.7525 14408.23 60 secs      240.1371
#> 3 2012-11-12 02:10:41     1 76.90897 -110.8613 52065.53 60 secs      867.7588
#> 4 2012-11-12 03:18:41     2 76.11152 -110.2037       NA NA secs            NA
#> 5 2012-11-12 03:19:41     2 76.29013 -110.3838 20507.15 60 secs      341.7859
#> 6 2012-11-12 03:20:41     2 76.15544 -110.4506 15140.03 60 secs      252.3338

单位为米/秒;随你转换。

答案 1 :(得分:1)

如果您倾向于使用data.table,请按以下步骤操作:

df[, Timestamp := parse_datetime(Timestamp)]
df[, distance := distVincentyEllipsoid(p1 = cbind(lon, lat), 
                                       p2 = cbind(shift(lon), shift(lat))), 
   by = ID]
output <- df[, .(time_diff = as.numeric(Timestamp[.N] - Timestamp[1], unit = "secs") ,
                 tot_distance = sum(distance, na.rm = TRUE)), by = ID]
output[, avg_speed := tot_distance /time_diff]
##    ID time_diff tot_distance avg_speed
## 1:  1       120     66473.26  553.9438
## 2:  2       120     35646.55  297.0546