基于数据框中重复日期序列生成批次ID列的技术问询
解决方案
dplyr 实现(推荐,匹配你的日常使用习惯)
利用cumsum()对day == 1的情况做累加,每遇到一次day=1,累加值就递增1,最后将累加值格式化为"batch X"的形式:
library(dplyr) set.seed(20) df <- data.frame(subject1 = runif(n=90, min = 1, max = 100), subject2 = runif(n=90, min = 1, max = 100), subject3 = runif(n=90, min = 1, max = 100), day = c(rep(1:21, 2), 1:28, 1:20)) # 生成batch ID列 df <- df %>% mutate(ID = paste0("batch ", cumsum(day == 1))) # 验证结果 head(df, 25) tail(df, 25)
这个方法是向量化操作,无循环开销,即使是超大规模数据集也能高效处理。
Base R 实现
无需加载任何包,原生R代码即可完成:
set.seed(20) df <- data.frame(subject1 = runif(n=90, min = 1, max = 100), subject2 = runif(n=90, min = 1, max = 100), subject3 = runif(n=90, min = 1, max = 100), day = c(rep(1:21, 2), 1:28, 1:20)) df$ID <- paste0("batch ", cumsum(df$day == 1))
data.table 实现(适配超大规模数据集)
如果数据集达到千万级以上行数,data.table的处理速度会更优:
library(data.table) set.seed(20) dt <- data.table(subject1 = runif(n=90, min = 1, max = 100), subject2 = runif(n=90, min = 1, max = 100), subject3 = runif(n=90, min = 1, max = 100), day = c(rep(1:21, 2), 1:28, 1:20)) dt[, ID := paste0("batch ", cumsum(day == 1))]
核心原理
cumsum(day == 1)会将每行day是否等于1转换为布尔值(TRUE对应1,FALSE对应0),再对这个序列累加:
- 第一行
day=1,累加值为1; - 后续20行
day≠1,累加值保持1; - 第22行
day=1,累加值变为2,以此类推。
最后用paste0()将前缀与累加值拼接成目标ID格式。
内容的提问来源于stack exchange,提问作者Bugs93
相关产品推荐
相关产品推荐

