You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按2小时间隔过滤GPS点位数据并保留符合条件记录?

筛选GPS数据:保留时间间隔至少2小时的点位

我有一份包含GPS点位的数据集,需要筛选出时间间隔至少2小时的记录,移除间隔不足2小时的后续点位。

原始数据集

gps_data_animals_id    acquisition_time
348179              348179 2015-09-18 00:00:00
348180              348180 2015-09-18 01:45:00
348181              348181 2015-09-18 02:00:00
348182              348182 2015-09-18 02:15:00
348183              348183 2015-09-18 02:30:00
348184              348184 2015-09-18 04:30:00
348185              348185 2015-09-18 04:45:00
348186              348186 2015-09-18 05:00:00
348187              348187 2015-09-18 06:00:00
348188              348188 2015-09-18 12:00:00
348189              348189 2015-09-18 17:15:00
348190              348190 2015-09-18 17:30:00
348191              348191 2015-09-18 17:45:00
348192              348192 2015-09-18 18:00:00
348193              348193 2015-09-18 18:15:00
348194              348194 2015-09-18 18:30:00
348195              348195 2015-09-18 18:45:00
348196              348196 2015-09-19 00:00:00
348197              348197 2015-09-19 06:01:00
348198              348198 2015-09-19 11:15:00

期望过滤结果

gps_data_animals_id    acquisition_time
348179              348179 2015-09-18 00:00:00
348181              348181 2015-09-18 02:00:00
348184              348184 2015-09-18 04:30:00
348188              348188 2015-09-18 12:00:00
348189              348189 2015-09-18 17:15:00
348196              348196 2015-09-19 00:00:00
348197              348197 2015-09-19 06:01:00
348198              348198 2015-09-19 11:15:00

尝试过的方法(存在问题)

我试过用lag()结合tapply()计算时间差,代码如下,但这种方法会误删像gps_data_animals_id = 348181这类符合条件的记录:

dataset$time_diff <- unlist(tapply(dataset$acquisition_time, INDEX = dataset$animals_id,
                                 FUN = function(x) c(0, `units<-`(diff(x), "hours"))))

问题出在:这段代码计算的是每条记录和上一条原始记录的时间差,而不是和最后一条被保留的记录的时间差。比如348181和上一条348180的间隔只有0.25小时,会被误判为不符合,但它和第一条348179的间隔刚好2小时,实际应该保留。

解决思路与代码

这类场景需要跟踪最后一条被保留记录的时间,让每条新记录都和这个时间对比,而不是和原始数据的上一条比。以下是两种实现方式:

方式1:基础循环实现

# 加载可复现数据集
dataset <- structure(list(gps_data_animals_id = 348179:348198, acquisition_time = structure(c(1442534400, 
1442540700, 1442541600, 1442542500, 1442543400, 1442550600, 1442551500, 
1442552400, 1442556000, 1442577600, 1442596500, 1442597400, 1442598300, 
1442599200, 1442600100, 1442601000, 1442601900, 1442620800, 1442642460, 
1442661300), class = c("POSIXct", "POSIXt"), tzone = "GMT")), row.names = 348179:348198, class = "data.frame")

# 初始化保留的索引和最后保留时间
keep_idx <- c(1)
last_kept_time <- dataset$acquisition_time[1]

# 逐行遍历判断
for (i in 2:nrow(dataset)) {
  current_time <- dataset$acquisition_time[i]
  # 计算与最后保留记录的时间差(单位:小时)
  time_diff <- as.numeric(difftime(current_time, last_kept_time, units = "hours"))
  if (time_diff >= 2) {
    keep_idx <- c(keep_idx, i)
    last_kept_time <- current_time
  }
}

# 筛选得到结果
filtered_data <- dataset[keep_idx, ]
print(filtered_data)

方式2:用purrr包的累积函数实现(更简洁)

library(purrr)

# 加载数据(同上面的dataset)
dataset <- structure(list(gps_data_animals_id = 348179:348198, acquisition_time = structure(c(1442534400, 
1442540700, 1442541600, 1442542500, 1442543400, 1442550600, 1442551500, 
1442552400, 1442556000, 1442577600, 1442596500, 1442597400, 1442598300, 
1442599200, 1442600100, 1442601000, 1442601900, 1442620800, 1442642460, 
1442661300), class = c("POSIXct", "POSIXt"), tzone = "GMT")), row.names = 348179:348198, class = "data.frame")

# 用accumulate跟踪最后保留的时间,标记需要保留的记录
keep_flag <- accumulate(dataset$acquisition_time, function(last, current) {
  if (as.numeric(difftime(current, last, units = "hours")) >= 2) {
    current
  } else {
    last
  }
}, .init = dataset$acquisition_time[1])

# 处理标记:去掉初始值,判断当前时间是否等于累积的最后保留时间(等于则保留)
keep_flag <- keep_flag[-1] == dataset$acquisition_time
# 第一条记录默认保留
keep_flag <- c(TRUE, keep_flag)

# 筛选结果
filtered_data <- dataset[keep_flag, ]
print(filtered_data)

两种方式都能得到你期望的过滤结果,核心逻辑都是跟踪最后一条被保留记录的时间,确保后续记录只和这个时间对比。

内容的提问来源于stack exchange,提问作者mto23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 06:43:12