различное n (смещение) для сдвига внутри каждой группы - PullRequest
0 голосов
/ 20 июня 2020

Хотелось бы вычислить время, прошедшее между действием A и действием X. Для других действий существуют разные логики c (B, C et c.), Но они предполагают аналогичные различия во времени.

Есть ли способ использовать вычисленное значение для смещения сдвига? В прошлом я использовал сдвиг для фиксированного смещения, например, используя задержку до go назад на 12 строк в группе, но не могу понять, как включить условное смещение в сдвиг

Вот вымышленный пример:

x <- data.table(Case = c(1,1,1,1,2,2,2,3,3,3,3,3), Action = c("A","B","C","X","A","X","X","A","C","X","A","X"), ActionTime = parse_date_time(c("1/23/2020 12:55","1/26/20 3:23","1/28/2020 4:23","4/16/2020 17:50","1/25/2020 23:04","2/12/2020 17:50","2/13/2020 17:50","1/26/2020 3:23","2/18/2020 21:23","2/18/2020 21:27","3/15/2020 3:23","3/18/2020 21:27"), orders=c('mdy HM')))
setkeyv(x, c("Case", "ActionTime"))

    > x
    Case Action          ActionTime
 1:    1      A 2020-01-23 12:55:00
 2:    1      B 2020-01-26 03:23:00
 3:    1      C 2020-01-28 04:23:00
 4:    1      X 2020-04-16 17:50:00
 5:    2      A 2020-01-25 23:04:00
 6:    2      X 2020-02-12 17:50:00
 7:    2      X 2020-02-13 17:50:00
 8:    3      A 2020-01-26 03:23:00
 9:    3      C 2020-02-18 21:23:00
10:    3      X 2020-02-18 21:27:00
11:    3      A 2020-03-15 03:23:00
12:    3      X 2020-03-18 21:27:00

Случай 1 - это простой случай, Случай 2, когда действие X отображается несколько раз, но мне нужно минимальное значение времени, и Группа 3, где A и X отображаются несколько раз в одном и том же случае.

Я хочу получить XTime = timestmp ближайшего X после появления A в случае:

    Case Action          ActionTime          XTime
 1:    1      A 2020-01-23 12:55:00          2020-04-16 17:50:00
 2:    1      B 2020-01-26 03:23:00
 3:    1      C 2020-01-28 04:23:00
 4:    1      X 2020-04-16 17:50:00
 5:    2      A 2020-01-25 23:04:00          2020-02-12 17:50:00
 6:    2      X 2020-02-12 17:50:00
 7:    2      X 2020-02-13 17:50:00
 8:    3      A 2020-01-26 03:23:00          2020-02-18 21:27:00
 9:    3      C 2020-02-18 21:23:00
10:    3      X 2020-02-18 21:27:00
11:    3      A 2020-03-15 03:23:00          2020-03-18 21:27:00
12:    3      X 2020-03-18 21:27:00

Оцените любую помощь

Спасибо

1 Ответ

1 голос
/ 20 июня 2020

Вот подход с скользящим соединением.

Сначала мы подмножества данных на Action == "A" и Action == "X" и соединяем эти два подмножества друг с другом. Мы используем on = c("Case","Time"), чтобы присоединиться к одинаковым делам, а затем по времени. В data.table вы можете выполнить бросок только по последнему условию соединения. Затем мы используем roll = Inf для отката. По какой-то причине столбец, который вы прокручиваете, объединяется во время соединения, поэтому мы создаем дополнительную копию с именем InitialTime.

Прокручивающееся соединение перемещается вперед до всех возможных значений в положительном направлении, поэтому мы подмножество на Case до минимума Time для всех комбинаций Case и InitialTime.

library(data.table)
data[Action == "A",.(Case,Action,Time,InitialTime=Time)][
  data[Action == "X",], on = c("Case","Time"), roll = Inf][
    ,.SD[which.min(Time),.(XTime=Time)],by = .(Case,InitialTime)]
   Case         InitialTime               XTime
1:    1 2020-01-23 12:55:00 2020-04-16 17:50:00
2:    2 2020-01-25 23:04:00 2020-02-12 17:50:00
3:    3 2020-01-26 03:23:00 2020-02-18 21:27:00
4:    3 2020-03-15 03:23:00 2020-03-18 21:27:00

Пример данных

data <- structure(list(Case = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 
3L, 3L), Action = structure(c(1L, 2L, 3L, 4L, 1L, 4L, 4L, 1L, 
3L, 4L, 1L, 4L), .Label = c("A", "B", "C", "X"), class = "factor"), 
    Time = structure(c(1579802100, 1580026980, 1580203380, 1587073800, 
    1580011440, 1581547800, 1581634200, 1580026980, 1582078980, 
    1582079220, 1584256980, 1584581220), class = c("POSIXct", 
    "POSIXt"), tzone = "")), row.names = c(NA, -12L), class = c("data.table", 
"data.frame"))
...