确定在x天内发生给定事件序列的记录

时间:2016-11-23 19:10:23

标签: r data.table

我有一个大的data.table,结构类似于df

library("data.table")
df <- data.frame(part = c("A", "B", "A", "C", "A", "D", "B", "D", "E"), 
                 day = c(1, 2, 3, 4, 5, 6, 6, 7, 15), 
                 code = c("S", "S", "P", "X", "P", "S", "P", "P", "P"))
setDT(df)
df
   part day code
1:    A   1    S
2:    B   2    S
3:    A   3    P
4:    C   4    X
5:    A   5    P
6:    D   6    S
7:    B   6    P
8:    D   7    P
9:    E  15    P

如何在随后的3天内添加一个标记记录code = S且同一part code = P的记录的列?预期结果:

   part day code  flag
1:    A   1    S  TRUE
2:    B   2    S FALSE
3:    A   3    P FALSE
4:    C   4    X FALSE
5:    A   5    P FALSE
6:    D   6    S  TRUE
7:    B   6    P FALSE
8:    D   7    P FALSE
9:    E  15    P FALSE

2 个答案:

答案 0 :(得分:6)

我认为这样做

df[, v := FALSE ]
df[code == "S", v := !is.na(
  df[code == "P"][df[code == "S"], on=c("part", "day"), roll=-3, which=TRUE]
)]

   part day code     v
1:    A   1    S  TRUE
2:    B   2    S FALSE
3:    A   3    P FALSE
4:    C   4    X FALSE
5:    A   5    P FALSE
6:    D   6    S  TRUE
7:    B   6    P FALSE
8:    D   7    P FALSE
9:    E  15    P FALSE

工作原理 !is.na(x[i, which=TRUE])告诉我们i的每一行是否在x中找到匹配项。 (如果i找到多个匹配项,这可能会中断。)roll部分会扩展匹配范围,以涵盖最后一列加入on附近的行。

我不确定roll值是否正确,因为我从未使用过这种方式。

答案 1 :(得分:1)

这也可以起作用 -

df$v <- as.logical((df$code== "S") *
        c(sapply(seq(1:(nrow(df)-2)), function(x)
           {
            max(df[(x:x+2),"code"] == "P")
           }),
          df[nrow(df)-1,"code"]=="P",
          df[nrow(df),"code"]=="P"))