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

cumsum、difftime、lag函数使用问题:连续yes行时间差计算异常

解决连续buffer="yes"序列的停留时长计算问题

你的数据集包含buffer(标记GPS点是否在缓冲区,值为yes/no)、DateTime(GPS点时间)、dt1(缓冲区停留时长)三列,按tripID分组处理。目前单个yes行能正确计算与前一行的时间差,但连续yes行的dt1返回NA,你需要在连续yes序列的最后一行填入该序列首尾GPS点的时间差。

原代码里的cumsum逻辑不对——它会给每个连续yes行都累加时间差,而不是只在最后一行生成首尾时间差。可以用以下方法修正:

解决方案代码

library(dplyr)
library(data.table) # 用到rleid函数识别连续序列

trips_with_buffer_2016_df <- trips_with_buffer_2016_df %>%
  group_by(tripID) %>%
  # 生成连续buffer状态的分组ID,每个连续的yes/no序列对应唯一id
  mutate(buffer_group = rleid(buffer)) %>%
  group_by(tripID, buffer_group) %>%
  mutate(
    # 计算当前buffer块的首尾时间差
    block_duration = as.numeric(difftime(max(DateTime), min(DateTime), units = "mins")),
    # 标记当前行是否是该buffer块的最后一行
    is_last_row = row_number() == n(),
    # 计算单个yes行的时间差(和前一行的间隔)
    single_yes_duration = ifelse(buffer == "yes" & n() == 1,
                                 as.numeric(difftime(DateTime, lag(DateTime), units = "mins")),
                                 NA_real_)
  ) %>%
  ungroup() %>%
  # 最终赋值dt1:连续yes的最后一行用block_duration,单个yes用single_yes_duration,其余为NA
  mutate(
    dt1 = case_when(
      buffer == "yes" & is_last_row & n() > 1 ~ block_duration,
      buffer == "yes" & n() == 1 ~ single_yes_duration,
      TRUE ~ NA_real_
    )
  ) %>%
  # 清理临时列
  select(-buffer_group, -block_duration, -is_last_row, -single_yes_duration) %>%
  # 重新按tripID分组(如果后续需要)
  group_by(tripID)

代码说明

  1. rleid(buffer):给每个连续的yes或no序列分配唯一分组ID,比如连续3个yes会被分到同一个buffer_group里。
  2. 按tripID + buffer_group分组:针对每个连续的buffer状态块计算首尾时间差,同时标记块内的最后一行。
  3. case_when逻辑:
    • 当是连续yes块的最后一行时,填入该块的首尾时间差
    • 当是单个yes行时,保留原逻辑计算与前一行的时间差
    • 其他情况(no行或连续yes的中间行)填NA

这样就能精准实现你要的效果:单个yes行填与前一行的时间差,连续yes序列仅最后一行填首尾时间差,其余yes行和所有no行的dt1为NA。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:35:15