基于data.table实现同组内事件的条件计数(适配大数据集)
高效data.table处理大型数据集:按ID分组统计特定唯一日期事件数
需求
针对大型数据集,使用高效的data.table方案,按ID分组统计满足以下条件的唯一日期事件数,并将结果添加为NR列:
- ATC字段以变量
code定义的"ABC"开头; - ATC_DATE > INDX_DATE。
示例数据
code <- c("ABC") DT <- data.table::data.table( ID = c(1L, 1L, 1L, 1L, 1L), INDX_DATE = c("2010-10-10","2010-10-11","2010-10-12", "2010-10-13","2010-10-13"), ATC = c("ABC123", "ABC12", "ABC", "DEF", NA), ATC_DATE = c("2005-05-05","2011-11-11","2012-12-12", "2011-11-11","2005-05-05") )
期望输出
ID INDX_DATE ATC ATC_DATE NR 1: 1 2010-10-10 ABC123 2005-05-05 2 2: 1 2010-10-11 ABC12 2011-11-11 2 3: 1 2010-10-12 ABC 2012-12-12 2 4: 1 2010-10-13 DEF 2011-11-11 2 5: 1 2010-10-13 <NA> 2005-05-05 2
逻辑说明
统计每个ID下,满足ATC以code值开头且ATC_DATE晚于INDX_DATE的唯一日期事件总数,将该数值赋值给每一行的NR列。
解决方案
考虑到大型数据集的效率,以下方案在分组内仅一次性提取有效日期,避免重复计算:
# 先将字符型日期转换为Date类型,确保日期比较准确 DT[, c("INDX_DATE", "ATC_DATE") := lapply(.SD, as.Date), .SDcols = c("INDX_DATE", "ATC_DATE")] # 按ID分组计算NR列 DT[, NR := { # 提取当前ID下所有符合ATC开头条件的非空ATC_DATE valid_dates <- ATC_DATE[startsWith(ATC, code) & !is.na(ATC)] # 遍历每一行的INDX_DATE,统计有效日期中大于它的唯一日期数量 sapply(INDX_DATE, function(x) length(unique(valid_dates[valid_dates > x]))) }, by = ID]
方案说明
- 日期类型转换:将原数据中的字符型日期列转为
Date类型,保证日期比较的正确性; - 分组内预提取有效日期:在每个ID分组内,先筛选出符合ATC开头条件的所有ATC_DATE,避免每行重复筛选,提升效率;
- 批量计算NR值:通过
sapply遍历分组内的每个INDX_DATE,统计满足ATC_DATE > INDX_DATE的唯一日期数,最终赋值给NR列。
内容的提问来源于stack exchange,提问作者hklovs
相关产品推荐
相关产品推荐

