首页 > 解决方案 > 在忽略重复日期的同时确定哪个组具有事件序列

问题描述

我使用 SPADE 算法识别了医疗记录(>2000 万条记录)中的频繁事件序列。现在我想确定哪个ID(组)有序列。该序列必须在 182 天内发生。同一天发生的任何事件(即items== R-S, bxR01, S-O)不应被视为一个序列(这具有随机顺序)。

开始,我有一个 long data.table,每行包含多行ID,每天一行包含列items中的一个或多个items(请参见下面的可重现示例)。

获得序列的一种方法似乎是拆分items包含多个事件并为每个 182 天的时间段制作行(使data.table长甚至更长),然后在182 天的时间内data.table为每个项目制作一个宽(不同的行在items同一每天ID)。

我不知道从哪里开始,所以我尝试以我能想到的小步骤减少所有内容,但进入了下面描述的兔子洞......我确实认为这个线程的第一条评论可能会有所帮助(但我不确定如何)。

我管理的是通过以下方式选择包含items序列中任何一个的所有行(即,从中创建一个新的data.table):

DT2 <- DT[grepl("bxD01", items) | grepl("S-In", items)]

然后我可以像这样使用 unnest:

DT2 = DT2 %>% 
    mutate(items = strsplit(as.character(items), ",")) %>% 
    unnest(items)

删除所有不相关的项目:

DT2 <- DT[grepl("bxD01", items) | grepl("S-In", items)] 

然后reorderaggregate

DT2 = DT2[order(ID,days)]
# aggregate to all items in one row/cell
DT3 = as.data.table(aggregate(as.formula(items~ID), data=DT2, FUN = toString))

但是,这(除了效率极低之外)不会为重复的日子制作不同的行……我想我会使用上面提到的类似的东西。

样本(模拟)数据

DT <-    structure(list(items = c("bxM01, T-Other", "bxD01", "S-In", 
"bxD02", "L-I", "A9", "R-S, bxR01, bxR03", 
"bxA02", "HDTR", "S-In", "HVAL", "SC.R", "bxD11, S-Other", 
"SC.R", "K-Other", "bxD06, S-In", "A-s.spec", "LON", 
"bxJ01", "S-Other", "HVAL, SC.R", "bxN02, bxN02, bxC07, S-Other", 
"K-Other", "A-s.spec", "bxC09", "R-all-rhin", "S-S, bxD07, bxD01", 
"S-In", "bxD07, ECZM", "X-resp-prev", "bxD07", "HVAL", 
"T-Other", "bxA11", "HVAL", "HVAL", "P-S", "K-Other", 
"bxN01, NKSH", "A-s.spec", "bxJ01", "X-resp-prev", "D-S", 
"FYS, B-Other", "K-Other", "bxC07, RON, NKSH", "bxM01, bxA01", 
"bxS01", "NKSH", "T-Other", "bxC08", "bxD04, K-Other", "bxN02", 
"bxD07, Y-S", "bxD07, bxR06, ALGY", "bxJ01", "SC.R, S-In", 
"bxD10", "bxD10", "bxJ01", "SC.R", "S-In", "L-I", 
"Y-S", "S-S", "K-Other", "bxR03, LON", "S-In", 
"RON, S-Ne", "S-In", "S-In", "SC.R", 
"S-In", "S-Other", "Z-S", "SX", "NKSH", "F-In, bxS01", 
"N-Other", "FYS, NKSH", "bxN02, TROT", "S-Sdf", "OBES", 
"bxJ01, bxN02, K-Other", "bxR01, LAB, TROT", "OBES", "K-Other", 
"A-Unknown", "Z-S", "K-S", "OBES", "bxM01, bxA02", 
"SC.R", "L-Other", "bxD02", "X-Other", "bxN05", "bxR06", 
"bxJ01, bxA02, bxN02", "TROT"), days = c(613L, 861L, 883L, 
1210L, 1408L, 1699L, 391L, 409L, 745L, 1448L, 28L, 32L, 43L, 
98L, 105L, 231L, 439L, 442L, 446L, 544L, 704L, 801L, 845L, 846L, 
851L, 1097L, 1131L, 1168L, 1246L, 1264L, 1309L, 1313L, 1323L, 
1327L, 1452L, 1475L, 1482L, 1484L, 1518L, 1588L, 1629L, 1630L, 
1631L, 1634L, 1641L, 1645L, 1699L, 1727L, 1741L, 1769L, 1809L, 
28L, 790L, 953L, 999L, 1004L, 1013L, 1015L, 1034L, 1055L, 1168L, 
1190L, 1211L, 1375L, 1544L, 1802L, 241L, 353L, 416L, 437L, 451L, 
547L, 548L, 706L, 831L, 832L, 839L, 1099L, 1276L, 1301L, 1567L, 
1598L, 287L, 574L, 854L, 872L, 943L, 1089L, 1147L, 1170L, 1177L, 
1201L, 1202L, 1512L, 20L, 30L, 52L, 53L, 87L, 309L), ID = c("G", 
"G", "G", "G", "G", "G", "F", "F", "F", "F", "E", "E", "E", "E", 
"E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", 
"E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", 
"E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "D", "D", 
"D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", 
"C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", 
"C", "C", "C", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", 
"B", "B", "A", "A", "A", "A", "A", "A")), row.names = c(NA, -100L
), class = c("data.table", "data.frame"))

样本(模拟)序列列表

seq <-structure(list(sequence = c("<{bxD01},{S-In}>", "<{L-s.spec}, TROT}>", "<{NKSH},{T-Other}>", "<{ABDO},{SC.REF}>",                                             "<{NKSH},{RON}>", "<{NKSH},{R-S}>", "<{P-S},{R-S}>", "<{L-s.spec},{P-S}>", "<{NKSH},{P-S}>", "<{ABDO},{NKSH}>")), 
             row.names = c(NA, -45L), class = c("data.table", "data.frame"))

总而言之,我需要一个包含二进制表达式的 data.table,该表达式指示ID在 182 天内是否有序列。

****编辑**** 我忘记添加我必须在 data.table 中选择序列的代码:

# reg expression for matching based on order
seq[, sequence_list := paste0(".*", gsub("[,]", "\\s*(.*?)\\", gsub("[</{/}>]", "", as.character(sequence))), ".*")]

# loop for every item in the sequence list (regex expression) and then label it as the sequence result
for (NUM in 1:length(seq$sequence_list[1])) {
  DT3[grepl(seq$sequence_list[1], x = items), RES_GROUP := seq$sequence[1]]
 DT3[grepl(seq$sequence_list[1], x = items), RES_GROUP_label := 1]
} 

非常欢迎任何帮助:)


不是很清楚这个问题在问什么,因此提出了这个编辑。以下是否举例说明了您正在寻找的内容?谢谢,是的,这就是我要问的。我还发布了另一个问题(并回答了部分问题)以澄清,但您的编辑可能会更清楚。

treatls <- data.table(SID=c(1,1,1,2,2), ITEM=c("A","C","D","B","D"))
#   SID ITEM
#1:   1    A  
#2:   1    C
#3:   1    D
#4:   2    B
#5:   2    D

DT <- rbindlist(list(
    data.table(ITEMS=c("A, B", "C", "D"), DAY=c(1,90,182), ID=rep(1L, 3L)),
    data.table(ITEMS=c("A", "C", "D"), DAY=c(1,90,200), ID=rep(2L, 3L))))[,
        DESIRED_HAS_SEQ := c(rep(TRUE, 3L), rep(FALSE, 3L))]

#   ITEMS DAY ID DESIRED_HAS_SEQ
#1:  A, B   1  1            TRUE
#2:     C  90  1            TRUE
#3:     D 182  1            TRUE
#4:     A   1  2           FALSE
#5:     C  90  2           FALSE
#6:     D 200  2           FALSE

标签: rregexdplyrdata.tablegrepl

解决方案


推荐阅读