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

使用lag()对比DataFrame行数据实现GPS POI识别的代码问题咨询

代码问题分析
  • 核心逻辑错误:lag()函数的使用完全不符合需求
    lag()只能提取同一分组下上一条相邻记录的字段值,你要实现的是匹配「当前时间+3分钟后30秒区间内的任意记录」,和相邻上一行没有任何关系。你代码里的min3 <= lag(min3)条件完全没有用到你设置的时间偏移逻辑去匹配对应时间的记录,只是比较相邻两行的min3值,不管你把偏移量改成3分钟还是1小时,相邻行的判断逻辑都不会变,所以结果完全一致。
  • 条件逻辑不符合需求
    你当前的stay判断逻辑只是校验相邻两行的经纬度是否一致、且当前行的min3小于等于上一行的min3(按时间升序排列的话这个条件几乎永远不成立),完全没有实现「校验3分钟后区间内的记录经纬度是否一致」的核心需求。
正确实现思路

你需要对每一条记录,匹配同一id下,时间落在[当前Timestamp + 180秒, 当前Timestamp + 210秒]区间内的所有记录,判断是否存在经纬度和当前记录一致的条目,存在则说明该位置满足停留要求,属于候选POI。

示例实现代码

针对中小数据量可以用dplyr的行式处理逻辑:

library(dplyr)
library(purrr)

POI_gps <- locations_gps %>%
  group_by(id) %>%
  arrange(Timestamp, .by_group = TRUE) %>%
  mutate(
    # 定义匹配的时间区间:+3分钟 到 +3分30秒
    start_match = Timestamp + 3*60,
    end_match = Timestamp + 3*60 +30
  ) %>%
  rowwise() %>%
  mutate(
    # 校验区间内是否有相同经纬度的记录
    stay = any(
      locations_gps$id == id & 
      locations_gps$Timestamp >= start_match & 
      locations_gps$Timestamp <= end_match &
      locations_gps$lat == lat &
      locations_gps$long == long
    )
  ) %>%
  ungroup() %>%
  filter(stay == TRUE) %>%
  distinct(id, lat, long)

如果数据量较大(十万条以上),推荐使用data.table的非等值连接实现,性能会高很多:

library(data.table)
setDT(locations_gps)
# 按id和时间排序
setkey(locations_gps, id, Timestamp)
# 生成待匹配的区间表
match_dt <- locations_gps[, .(id, Timestamp, lat, long, start_match = Timestamp + 180, end_match = Timestamp + 210)]
# 非等值连接匹配区间内的记录
joined <- match_dt[locations_gps, on = .(id, start_match <= Timestamp, end_match >= Timestamp), nomatch = 0]
# 筛选经纬度一致的记录,去重得到POI
POI_gps <- unique(joined[lat == i.lat & long == i.long, .(id, lat, long)])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 22:03:03