2016-09-01 3 views
1

У меня есть таблица данных, как это:Подменит на основе шаблонов в данных

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, если существует положительное значение 1 и 2 строки (включительно) до возникновения отрицательной.

С уважением

+0

Не должно ли последнее значение быть 1? –

+0

Меня беспокоит только то, что оно встречается 1 или 2 строки перед отрицательным в столбце b. –

+2

Так где же происходит подстановка? Кроме того, в вашем примере вы сначала указываете: «если в столбце b было положительное значение, две строки были ранее». Затем вы указываете «дать 1, если было положительное значение 1 и 2 строки (включительно) до отрицательного произошло «. и в комментарии выше вы говорите «1 ИЛИ 2 строки раньше» ... какой из них? Если это 1 ИЛИ 2, не все будут 1? – Sotos

ответ

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 ОТВЕТ: Вы можете использовать функцию 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 
+2

может быть в конечном итоге оптимизирован для одиночного вызова 'shift' внутри' {', когда [data.table # 1708] (https://github.com/Rdatatable/data.table/issues/1708) реализовано – jangorecki

+1

@jangorecki, что было бы неплохо ! – Jaap

Смежные вопросы