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

R语言按ID分组删除组内时间间隔小于5分钟的冗余行实现方法

实现方法

你之前的代码出错原因有两个:一是没有按ID分组处理,不同ID的记录时间差被错误计算;二是判断逻辑是和相邻的上一条记录比,而规则要求是和上一条被保留的记录比,当有连续多条间隔不足5分钟的记录时,就会出现判断错误。

以下提供两种可直接运行的实现方案,180个ID的规模下运行效率完全满足需求:

方案1:tidyverse套件实现(代码简洁易读)

# 加载依赖包
library(dplyr)
library(purrr)
library(lubridate)

# 1. 数据预处理:转换时间格式、按ID+时间升序排序
df <- df %>%
  mutate(Timestamp = ymd_hms(Timestamp)) %>%
  arrange(ID, Timestamp)

# 2. 定义保留逻辑判断函数
filter_func <- function(last_keep_time, current_time) {
  # 当前记录和上一条保留记录间隔≥5分钟则保留当前时间,否则沿用上次保留的时间
  if (difftime(current_time, last_keep_time, units = "mins") >= 5) {
    return(current_time)
  } else {
    return(last_keep_time)
  }
}

# 3. 分组筛选符合要求的记录
df_cleaned <- df %>%
  group_by(ID) %>%
  mutate(keep_time = accumulate(Timestamp, filter_func)) %>%
  filter(Timestamp == keep_time) %>% # 仅保留时间匹配的记录
  ungroup() %>%
  select(-keep_time) # 删除辅助计算列

方案2:base R实现(无需安装额外包)

# 1. 转换时间格式
df$Timestamp <- as.POSIXct(df$Timestamp, format = "%Y-%m-%d %H:%M:%S")
# 2. 按ID+时间升序排序
df <- df[order(df$ID, df$Timestamp), ]
# 3. 按ID拆分数据集分别处理
df_list <- split(df, df$ID)
df_cleaned_list <- lapply(df_list, function(sub_df) {
  keep_rows <- c(1) # 同ID下最早的记录默认保留
  last_keep_time <- sub_df$Timestamp[1]
  for (i in 2:nrow(sub_df)) {
    current_time <- sub_df$Timestamp[i]
    if (difftime(current_time, last_keep_time, units = "mins") >= 5) {
      keep_rows <- c(keep_rows, i)
      last_keep_time <- current_time
    }
  }
  return(sub_df[keep_rows, ])
})
# 4. 合并处理后的结果
df_cleaned <- do.call(rbind, df_cleaned_list)
# 如果需要恢复原数据集的行顺序,可再加以下代码
# df_cleaned <- df_cleaned[order(df_cleaned$Row), ]

效果验证

用你提供的样例数据测试,最终保留的记录对应原行号为1、2、5、6、8、9、10,完全符合规则要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:39:03