скользящее вычисление для следующих или предыдущих значений в таблице данных

#r #data.table #compare #rolling-computation

#r #data.table #Сравнить #скользящее вычисление

Вопрос:

У меня есть data.table DT с 3 столбцами, Zeit , Spuer и Eingriff .

 DT <- data.table(Zeit = c(1, 2, 3, 4, 5, 6, 7, 8, 9), 
                 Spuer = c(45, 45, 32, 25, 30, 44, 34, 42, 44), 
                 Eingriff = c(0, 0, 1, 0, 0, 0, 1, 0, 0))
  

Я хочу выяснить, является ли Eingriff == 1 и одним из следующих 3 значений Spuer < 30 . Если это TRUE, то Eingriff == 1 else Eingriff == 0 . Для моих реальных данных я проверяю, являются ли следующие 20 или более значений Spuer меньше 30, поэтому такое решение, как lead (Spuer, 1), lead (Spuer, 2) и т. Д., Не является хорошим решением.

Я уже пытался реализовать решение с frollapply помощью and shift , но не смог заставить его работать.

В итоге результат должен выглядеть следующим образом:

 res <- data.table(Zeit = c(1, 2, 3, 4, 5, 6, 7, 8, 9), 
                  Spuer = c(45, 45, 32, 25, 30, 44, 34, 42, 44), 
                  Eingriff = c(0, 0, 1, 0, 0, 0, 0, 0, 0))
  

Ответ №1:

Вот один из вариантов, использующий sapply :

Сначала мы выясняем индексы, где Eingriff == 1 и для каждого из этих индексов проверяем, является ли any значение в window меньше 30.

 library(data.table)

window <- 3
inds <- which(DT$Eingriff == 1)

DT[inds, Eingriff := as.integer(sapply(inds, function(x) 
                              any(DT$Spuer[x:(x window - 1)] < 30)))]

DT
#   Zeit Spuer Eingriff
#1:    1    45        0
#2:    2    45        0
#3:    3    32        1
#4:    4    25        0
#5:    5    30        0
#6:    6    44        0
#7:    7    34        0
#8:    8    42        0
#9:    9    44        0
  

Ответ №2:

Вот еще один вариант, использующий неравнозначное соединение:

 k <- 3L
DT[, c("start", "end") := .(.I, .I   k)]
DT[Eingriff==1L, Eingriff :=
    DT[.SD, on=.(start>start, start<=end), by=.EACHI,  any(x.Spuer < 30)]$V1
]
  

вывод:

    Zeit Spuer Eingriff start end
1:    1    45        0     1   4
2:    2    45        0     2   5
3:    3    32        1     3   6
4:    4    25        0     4   7
5:    5    30        0     5   8
6:    6    44        0     6   9
7:    7    34        0     7  10
8:    8    42        0     8  11
9:    9    44        0     9  12