Представьте себе data.table
in R
, заданный
library(data.table)
dtable = data.table(
id = c(rep(1, 3), rep(2, 4), rep(3, 2)),
time = c(seq(1, 3, 1), seq(1, 4, 1), seq(3, 4)),
state_1 = c('A', 'A', 'B', 'A', 'B', 'B', 'B', 'A', 'A'),
state_2 = c('A', 'B', 'A', NA, 'B', 'B', NA, 'A', 'A')
)
, который оценивается как
id time state_1 state_2
1: 1 1 A A
2: 1 2 A B
3: 1 3 B A
4: 2 1 A <NA>
5: 2 2 B B
6: 2 3 B B
7: 2 4 B <NA>
8: 3 3 A A
9: 3 4 A A
Я хочу отследить, как долго каждое состояние в каждой строке находилось втекущее состояние.Я хочу считать мои данные как левые, так и нет.Т.е. одно решение всегда должно возвращать NA
для первых наблюдений каждого id
до тех пор, пока не наблюдаются изменения в состояниях.Другое решение должно относиться к первому наблюдению, как будто состояние только что изменилось на это состояние.Мой полученный data.table
должен вернуть
id time state_1 state_2 time_in_state_1_censored time_in_state_2_censored time_in_state_1 time_in_state_2
1: 1 1 A A NA NA 0 0
2: 1 2 A B NA 0 1 0
3: 1 3 B A 0 0 0 0
4: 2 1 A <NA> NA NA 0 0
5: 2 2 B B 0 0 0 0
6: 2 3 B B 1 1 1 1
7: 2 4 B <NA> 2 0 2 0
8: 3 3 A A NA NA 0 0
9: 3 4 A A NA NA 1 1
Я частично решил нецензурную часть, используя rle
(на id < 3
)
dtable[id < 3,
(paste0('time_in_', columns)) :=
lapply(.SD, function(col) unlist(sapply(rle(col)$lengths, function(x) 1:x-1))),
by='id', .SDcols = columns]
Но я уверенэто может быть решено умнее, надежнее и эффективнее, вероятно.