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

如何在R数据框中筛选时间更早的重复行?

高效筛选重复行并保留日期更早记录的Base R无循环方案

需求:从数据框中按var1列识别重复行,对每个重复的var1组,保留EndDate时间更早的行;非重复的var1行也全部保留。原实现用了for循环,现寻求更高效的Base R无循环方案。

原始数据

data <- structure(list(var1 = c("11", "11", 
                                "12", "12", "13", "13", 
                                "14", "14", "15", "16"
), EndDate = structure(c(1588792540, 1588942766, 1589118458, 
                         1589059900, 1588669654, 1588979219, 1588876217, 1588786020, 1588506698, 
                         1588512011), class = c("POSIXct", "POSIXt"), tzone = "UTC")), row.names = c(NA, 
                                                                                                     10L), class = "data.frame")

方案1:用ave()实现(最简洁)

# 按var1分组,筛选每组中EndDate最早的行
newdf <- data[ave(as.numeric(data$EndDate), data$var1, FUN = function(x) x == min(x)) == 1, ]

逻辑说明:

  • ave()是Base R的分组计算函数,按var1对EndDate(转成数值型方便比较)分组处理
  • 每组内判断当前行的EndDate是否等于该组的最小值(即最早日期),生成逻辑向量
  • 用这个向量筛选数据框,自动保留非重复组的唯一行,以及重复组中日期最早的行

方案2:用split()+lapply()实现(逻辑更直观)

# 拆分数据组→每组取日期最早行→合并结果
newdf2 <- do.call(rbind, lapply(split(data, data$var1), function(df) {
  df[which.min(df$EndDate), ]
}))
# 重置行名(可选,避免分组后行名带组标识)
rownames(newdf2) <- NULL

逻辑说明:

  • split(data, data$var1)把数据按var1拆分成多个子数据框的列表
  • 遍历每个子数据框,用which.min()找到EndDate最小的行索引,提取该行
  • 最后用rbind合并所有子结果,得到最终数据框

两种方案都完全避免了for循环,利用Base R的向量/分组运算特性,在数据量大时效率远高于循环实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:45:18