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

R语言:按ID分组并按日期排序生成测试序号及计算时间差

解决方案:为分组数据添加测试序号与时间差列

原始数据集

首先定义可复现的数据集:

id <- c("U1", "U2", "U3", "U2", "U5", "U5")
date <- c("2020-02-01", "2020-05-06", "2020-04-01", "2020-07-09", "2020-11-01", "2020-12-01")
result <- c(1:6)
dt <- data.frame(id, date, result)

原始输出:

> dt
  id       date result
1 U1 2020-02-01      1
2 U2 2020-05-06      2
3 U3 2020-04-01      3
4 U2 2020-07-09      4
5 U5 2020-11-01      5
6 U5 2020-12-01      6

需求说明

  1. 按唯一id分组,依据date排序后添加type列,标注该ID下的测试序号(如Result 1、Result 2)
  2. 新增time列:首次测试标注为First Test,后续测试显示与上一次测试的间隔天数

方法一:使用dplyr(tidyverse工具链,推荐)

这种方法代码简洁易读,适合数据处理场景:

# 加载dplyr包(若未安装先执行 install.packages("dplyr"))
library(dplyr)

dt_processed <- dt %>%
  # 将字符型日期转为Date类型,确保排序和时间计算准确
  mutate(date = as.Date(date)) %>%
  # 按id分组
  group_by(id) %>%
  # 组内按日期升序排序
  arrange(date, .by_group = TRUE) %>%
  # 生成测试序号列
  mutate(type = paste("Result", row_number())) %>%
  # 计算时间差:首行标记为First Test,其余行计算与前一行的间隔天数
  mutate(time = case_when(
    row_number() == 1 ~ "First Test",
    TRUE ~ paste(as.integer(date - lag(date)), "Days")
  )) %>%
  # 取消分组
  ungroup()

# 查看处理结果
print(dt_processed)

输出结果:

# A tibble: 6 × 5
  id    date       result type     time        
  <chr> <date>      <int> <chr>    <chr>       
1 U1    2020-02-01      1 Result 1 First Test  
2 U2    2020-05-06      2 Result 1 First Test  
3 U3    2020-04-01      3 Result 1 First Test  
4 U2    2020-07-09      4 Result 2 64 Days     
5 U5    2020-11-01      5 Result 1 First Test  
6 U5    2020-12-01      6 Result 2 30 Days     

方法二:基础R循环实现

若不想依赖第三方包,可使用基础R循环完成需求:

# 先将日期列转为Date类型
dt$date <- as.Date(dt$date)

# 初始化新增列
dt$type <- character(nrow(dt))
dt$time <- character(nrow(dt))

# 获取所有唯一ID
unique_ids <- unique(dt$id)

# 循环处理每个ID的数据
for (uid in unique_ids) {
  # 筛选当前ID的行
  idx <- dt$id == uid
  # 组内按日期排序
  sorted_data <- dt[idx, ]
  sorted_data <- sorted_data[order(sorted_data$date), ]
  
  # 生成测试序号
  sorted_data$type <- paste("Result", 1:nrow(sorted_data))
  
  # 设置时间列:首行标记为First Test,其余计算间隔天数
  sorted_data$time[1] <- "First Test"
  if (nrow(sorted_data) > 1) {
    for (i in 2:nrow(sorted_data)) {
      day_diff <- as.integer(sorted_data$date[i] - sorted_data$date[i-1])
      sorted_data$time[i] <- paste(day_diff, "Days")
    }
  }
  
  # 将处理后的数据放回原数据框
  dt[idx, ] <- sorted_data
}

# 保持原始行顺序(可选)
dt <- dt[as.integer(rownames(dt)), ]

# 查看结果
print(dt)

输出结果:

id       date result     type       time
1 U1 2020-02-01      1 Result 1 First Test
2 U2 2020-05-06      2 Result 1 First Test
3 U3 2020-04-01      3 Result 1 First Test
4 U2 2020-07-09      4 Result 2    64 Days
5 U5 2020-11-01      5 Result 1 First Test
6 U5 2020-12-01      6 Result 2    30 Days

内容的提问来源于stack exchange,提问作者M.Frumh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:45:30