首页 > 解决方案 > 在条件之前和之后的行中添加包含数据的列

问题描述

受这篇文章的启发,我想出了一个解决方案,在 y==5 之前和之后添加一个 1 的 2 行的列。像这样:

library(data.table)
DT <- fread("grp y exclude
            a 1 0
            a 2 0
            a 3 0
            a 4 1
            a 5 0
            a 7 1
            a 8 0
            a 9 0
            a 10 0
            b 1 0
            b 2 0
            b 3 0
            b 4 1
            b 5 0
            b 6 1
            b 7 1
            b 8 0
            b 9 0
            b 10 0
            c 5 1
            d 1 0")

DT[DT[, rn := .I][, rn[abs(.I - .I[y==5]) <= 2], by=grp]$V1, xx:=1]

我的问题是,如果条件太接近顶部,它会抛出警告并且无法正常工作:

DT$y[2] <- 5

DT[DT[, rn := .I][, rn[abs(.I - .I[y==5]) <= 2], by=grp]$V1, xx:=1]
Warning message:
In .I - .I[y == 5] :
  longer object length is not a multiple of shorter object length

我怀疑该索引会给出小于 1 的数字,但无法弄清楚。有什么建议可以更改代码以使其在所有条件下都能正常工作吗?

想要的输出:

    grp  y exclude xx
 1:   a  1       0  1
 2:   a  5       0  1
 3:   a  3       0  1
 4:   a  4       1  1
 5:   a  5       0  1
 6:   a  7       1  1
 7:   a  8       0  1
 8:   a  9       0  0
 9:   a 10       0  0
10:   b  1       0  0
11:   b  2       0  0
12:   b  3       0  1
13:   b  4       1  1
14:   b  5       0  1
15:   b  6       1  1
16:   b  7       1  1
17:   b  8       0  0
18:   b  9       0  0
19:   b 10       0  0
20:   c  5       1  1
21:   d  1       0  0

标签: rindexingdata.table

解决方案


这是另一种使用shift

val <- 5L
DT[, xx := as.integer(
        Reduce(`|`, c(shift(y==val, 0L:2L, fill=FALSE), shift(y==val, 1L:2L, FALSE, "lead")))
    ),
    by=.(grp)]
DT

结合 Jaap 的评论,使用 data.table 版本 >= 1.12.0,代码缩短为

DT[, xx := +(Reduce(`|`, shift(y==v, -2L:2L, FALSE))), by=grp]

输出:

    grp  y exclude xx
 1:   a  1       0  1
 2:   a  5       0  1
 3:   a  3       0  1
 4:   a  4       1  1
 5:   a  5       0  1
 6:   a  7       1  1
 7:   a  8       0  1
 8:   a  9       0  0
 9:   a 10       0  0
10:   b  1       0  0
11:   b  2       0  0
12:   b  3       0  1
13:   b  4       1  1
14:   b  5       0  1
15:   b  6       1  1
16:   b  7       1  1
17:   b  8       0  0
18:   b  9       0  0
19:   b 10       0  0
20:   c  5       1  1
21:   d  1       0  0
    grp  y exclude xx

推荐阅读