Используя порядковые индексы o
, упорядочите исходный фрейм данных по student_id
и date
.Теперь примените cumsum
на student_id
и pass/fail
к pass/fail
и, наконец, вернитесь к исходному порядку.
library(data.table)
o <- with(DF, order(student_id, date))
transform(DF[o, ],
streak = ave(`pass/fail`, rleid(student_id, `pass/fail`), FUN = cumsum))[order(o), ]
, получив:
ow student_id date pass.fail streak
1 1 2 2019-05-24 0 0
2 2 2 2019-05-25 -1 -1
3 3 1 2019-05-24 1 2
4 4 1 2019-05-28 -1 -1
5 5 2 2019-05-23 1 1
6 6 1 2019-05-27 1 3
7 7 2 2019-05-28 -1 -2
8 8 1 2019-05-23 1 1
Примечание
Ввод в воспроизводимом виде:
Lines <- "ow student_id date pass/fail streak
1 2 2019-05-24 0 0
2 2 2019-05-25 -1 -1
3 1 2019-05-24 1 2
4 1 2019-05-28 -1 -1
5 2 2019-05-23 1 1
6 1 2019-05-27 1 3
7 2 2019-05-28 -1 -2
8 1 2019-05-23 1 1"
DF <- read.table(text = Lines, header = TRUE, check.names = FALSE)
DF$date <- as.Date(DF$date)
DF$streak <- NULL