【发布时间】:2021-03-09 21:11:38
【问题描述】:
我正在一项模拟研究中使用 GPS 数据,这意味着我所有的小问题都会再次困扰我。
更大的问题之一是停止检测算法的实现。第一步是生成候选停靠点,在这里我确定在时间和空间上靠近的坐标。
这里有一些玩具数据:
library(data.table)
gcdist <- function(lat1, lon1, lat2, lon2){
sqrt((12430*abs(lat1 - lat2)/180)^2 +
((24901*abs(lon1 - lon2)/360) * cos((lat1+lat2)/2))^2)
}
time <- rev(Sys.time() - seq(60, 30*60, 60))
lat <- cumsum(c(55, rnorm(29, 0, sd = .003)))
lon <- cumsum(c(5.2, rnorm(29, 0, sd = .003)))
id <- 1:30
dt <-data.table(id, time, time_dup = time, lon, lat)
dt[, time_window := time + 60*3]
setkey(dt, time, time_window)
我目前正在使用 data.table 中的 foverlap。 Data.table 友好的解决方案是必须的,因为整个数据集接近 8GB。
这不足以在一个合适的时间线上运行我的模拟研究,而且它也不是很精确。因为我只在三分钟的窗口内查看然后停下来,我必须想办法处理它们的组合。
# Current setup
setkey(dt, time, time_window)
temp <- foverlaps(dt, dt, by.y = c("time", "time_window"), by.x = c("time", "time_dup"), type = "within")
temp[, dist := gcdist(lat, lon, i.lat, i.lon)]
temp[dist < .5, within_stop := TRUE]
temp[, candidate_stop := all(dist < .5), id]
setkey(temp, id)
setkey(dt, id)
dt[temp, candidate_stop := i.candidate_stop]
setkey(temp, i.id)
dt[temp, within_stop := i.within_stop]
这更接近我应该做的,但对于 8gb 的数据来说太麻烦了。
current_stop <- dt[1, ]
for (i in seq_len(nrow(dt))) {
dist <- gcdist(current_stop[, lat], current_stop[, lon],
dt[i, lat], dt[i, lon])
if(abs(dist) > .5) current_stop <- dt[i]
dt[i:nrow(dt), stop_id := current_stop[, id]]
}
我有一种预感,在 data.table 的滚动连接或 frollapply 中有适合我的东西。我一直在阅读这些页面并玩弄示例,但我无法让它发挥作用。我想我应该能够滚动应用距离窗口函数,直到距离大于某个截止值,然后重新启动,但如果我能弄清楚如何,我会打败我。
【问题讨论】:
标签: r data.table gps rolling-computation