根据数据模式对数据表进行子集

时间:2016-09-01 09:06:55

标签: r data.table

我有一个这样的数据表:

z
     a   b negflag
 1:  1  41       0
 2:  2  61       0
 3:  3 623       0
 4:  4 -12       1
 5:  5  10       0
 6:  6  15       0
 7:  7  16       0
 8:  8  -9       1
 9:  9  31       0
10: 10  10       0

我想要做的是在“negflag”旁边添加一个列,它告诉我b列中是否有正值,之前是2行。

像这样:

     a   b negflag posflag
 1:  1  41       0       0
 2:  2  61       0       1
 3:  3 623       0       1
 4:  4 -12       1       0
 5:  5  10       0       0
 6:  6  15       0       1
 7:  7  16       0       1
 8:  8  -9       1       0
 9:  9  31       0       0
10: 10  10       0       0

因此,如果在负面发生之前存在正值1和2行(包括),我希望另一列给出1。

问候

1 个答案:

答案 0 :(得分:7)

此答案的第一次迭代并未解释所提供的数据集中不存在的几种情况(尽管它确实提供了所提供数据的预期输出)。使用新的数据集znew,您将需要另一个过程来获得正确的输出,从而满足问题中的指定条件:

znew[, pf := as.integer(b < 0 & shift(b, fill = 0) > 0 & shift(b, n = 2L, fill = 0) > 0)
     ][, posflag := as.integer(shift(pf, type = 'lead', fill = 0)==1 | shift(pf, n = 2L, type = 'lead', fill = 0)==1)
       ][, pf := NULL]

或(根据@Frank的建议):

idx <- znew[, .I[b < 0 & do.call(pmin, shift(b, 1:2, fill=0L)) > 0]]
znew[, posflag := 0L][c(idx-1L, idx-2L), posflag := 1L]

两者都给出了:

> znew
     a   b negflag posflag
 1:  1 -41       1       0
 2:  2  61       0       1
 3:  3 623       0       1
 4:  4 -12       1       0
 5:  5  10       0       0
 6:  6 -15       1       0
 7:  7  16       0       0
 8:  8  -9       1       0
 9:  9  31       0       0
10: 10  10       0       0

两种方法首先确定是否满足条件(列b中的负值的前两个正值)并创建posflag变量。

使用过的数据

znew <- fread('a  b  negflag
 1   -41     1
 2    61     0
 3   623     0
 4   -12     1
 5    10     0
 6   -15     1
 7    16     0
 8    -9     1
 9    31     0
10    10     0')

OLD ANSWER:您可以使用shift中的data.table功能,如下所示:

z[, posflag := as.integer(b > 0 & shift(b) > 0 & (shift(b, type = 'lead', 
           fill = 0) < 0 | shift(b, n = 2L, type = 'lead', fill = 0) < 0))]

会给你:

> z
     a   b negflag posflag
 1:  1  41       0       0
 2:  2  61       0       1
 3:  3 623       0       1
 4:  4 -12       1       0
 5:  5  10       0       0
 6:  6  15       0       1
 7:  7  16       0       1
 8:  8  -9       1       0
 9:  9  31       0       0
10: 10  10       0       0