Хотя ФП попросил объяснить, почему его код не возвращает ожидаемый результат (на который указывает комментарий Грегора ), я хотел бы предложить альтернативный подход.
Если я правильно понимаю, ОП хочет найти все подпоследовательности в df1$number
, которые состоят из двух нулей, за которыми следуют два, то есть c(0, 0, 1, 1)
. Затем строка, содержащая первую последовательность в подпоследовательности, должна быть помечена 1
, тогда как все остальные строки должны получить 44
в качестве значения по умолчанию.
Начиная с версии v1.12.0 (на CRAN 13 января 2019 г.) с data.table
, функция shift()
распознает отрицательные параметры задержки / опережения. Таким образом, столбец может быть сдвинут на несколько значений в одном пакете. Номера строк, которые удовлетворяют вышеуказанному условию, идентифицируются последующей операцией соединения. Наконец, df1
обновляется выборочно, используя следующие номера строк:
# use enhanced sample dataset, rows 10 to 21 added
df1 <- data.frame(number = c(1,1,0,0,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1))
library(data.table)
setDT(df1)[, t := 44] # coerce to data.table, pre-populate result column
# shift and join
idx <- df1[, shift(number, 2:-1)][.(0, 0, 1, 1), on = paste0("V", 1:4), which = TRUE]
df1[idx, t := 1] # selective update
df1
number t
1: 1 44
2: 1 44
3: 0 44
4: 0 44
5: 0 44
6: 0 44
7: 0 44
8: 1 1
9: 1 44
10: 0 44
11: 1 44
12: 0 44
13: 1 44
14: 1 44
15: 0 44
16: 0 44
17: 1 44
18: 0 44
19: 0 44
20: 1 1
21: 1 44
number t
Это работает по существу как подход OP, сдвигая и сравнивая с ожидаемыми значениями. Однако подход OP требует кодирования четырех сравнений и трех операций сдвига, в то время как здесь сдвиг выполняется за один шаг, а сравнение всех столбцов одновременно выполняется операцией соединения на втором этапе.
Дополнительные пояснения
Сдвиг
df1[, shift(number, 2:-1)]
возвращает
V1 V2 V3 V4
1: NA NA 1 1
2: NA 1 1 0
3: 1 1 0 0
4: 1 0 0 0
5: 0 0 0 0
6: 0 0 0 0
7: 0 0 0 1
8: 0 0 1 1
9: 0 1 1 0
10: 1 1 0 1
11: 1 0 1 0
12: 0 1 0 1
13: 1 0 1 1
14: 0 1 1 0
15: 1 1 0 0
16: 1 0 0 1
17: 0 0 1 0
18: 0 1 0 0
19: 1 0 0 1
20: 0 0 1 1
21: 0 1 1 NA
V1 V2 V3 V4
В последующей операции соединения
df1[, shift(number, 2:-1)][.(0, 0, 1, 1), on = paste0("V", 1:4), which = TRUE]
which = TRUE
запрашивает возврат только индексов совпадающих строк, которые
[1] 8 20