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

如何在多行列的日期数据中提取第1、2、3早的日期?

解决思路与代码实现

针对你的需求,核心是把分散在多行多列的日期统一收集起来,按个体筛选出最早的三个日期,推荐用tidyverse工具链来实现,步骤清晰且易维护:

步骤说明

  1. 宽转长格式:把所有日期列合并成一列,消除多行多列的分散结构,同时过滤掉无效的NA日期。
  2. 分组排序取前3:按ID分组,对每个组内的日期从小到大排序,提取前3个最早的日期。
  3. 长转宽格式:将筛选后的日期转回每行一个ID的结构,方便查看。

完整代码(tidyverse版)

# 加载必要包
library(tidyverse)

# 1. 转换为长格式,清理NA日期
long_data <- Addim_try %>%
  pivot_longer(cols = -ID,  # 选中除ID外的所有日期列
               names_to = "date_source",  # 记录原日期列名(可选,可删除)
               values_to = "date") %>%
  filter(!is.na(date))  # 去掉空日期

# 2. 分组筛选前3早的日期并标记排名
top3_dates <- long_data %>%
  group_by(ID) %>%
  arrange(date, .by_group = TRUE) %>%  # 按日期升序排序
  slice_head(n = 3) %>%  # 取前3个最早的日期
  mutate(rank = paste0("earliest_date_", row_number())) %>%  # 标记第1/2/3早
  ungroup()

# 3. 转回宽格式得到最终结果
final_result <- top3_dates %>%
  pivot_wider(id_cols = ID, 
              names_from = rank, 
              values_from = date)

备选方案(base R版)

如果不想加载额外包,也可以用base R实现:

# 按ID聚合,收集所有有效日期并取前3早
agg_data <- aggregate(. ~ ID, data = Addim_try, FUN = function(x) {
  valid_dates <- na.omit(unlist(x))
  head(sort(valid_dates), 3)
})

# 将列表列拆分为单独的日期列
final_result_base <- do.call(data.frame, c(agg_data, stringsAsFactors = FALSE))
names(final_result_base)[-1] <- paste0("earliest_date_", 1:3)

注意事项

  • 如果某个个体的有效日期不足3个,结果中对应的earliest_date_*列会显示NA,符合实际情况。
  • 代码中保留了date_source列用于记录日期来自原数据集的哪一列,不需要的话可以在pivot_longer中删除该参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:18:34