Совокупные ряды закрываются во времени - PullRequest
3 голосов
/ 16 января 2020

У меня есть набор данных в R со следующим форматом:

data = data.table(
id = c(1, 2, 2, 2, 3, 3, 3, 3 ,3, 3),
Start = c("2019-03-01 09:15:36", 
"2019-01-01 08:00:00", "2019-01-01 08:00:10","2019-01-01 08:00:30",
"2019-01-01 08:00:30", "2019-01-01 08:00:40","2019-01-01 08:00:50",
"2019-01-01 08:01:10", "2019-01-01 08:01:20","2019-01-01 08:01:31"
))
data$Start = as.POSIXct(data$Start ,format = "%Y-%m-%d %H:%M:%S")

каждая строка представляет взаимодействие с человеком, с каждым человеком, идентифицированным идентификатором (В примере набора данных у меня есть 3 человека ). По определению, взаимодействия с менее чем 15 секунд между датами их начала должны быть объединены (считаться только как один). Это окно 15 с должно расширяться с каждым новым взаимодействием (см. Результат примера для лица 3).

Учитывая это правило, а для data я хочу создать столбец newID, который идентифицирует уникальное взаимодействие. Результаты должны быть такими:

data$newID 
[1] 1 2 2 3 4 4 4 5 5 5

Похоже, что-то должно быть возможно в data.table, без неэффективных циклов for, но я не могу заставить его работать ...

Ответы [ 3 ]

1 голос
/ 16 января 2020

Вдохновленный ответом @Sotos, я думаю, что правильное решение:

data$test = c(T,data$ID[-1] != data$ID[-nrow(data)] |
                           diff.difftime(data$Start) > 15)

Это генерирует логическое значение, в котором должны быть удалены все F (хотя это не создает новый идентификатор, согласно вопрос, это решило проблему неявного удаления).

1 голос
/ 16 января 2020

Один из способов сделать это - вычислить разницу и изменить группу каждый раз, когда значение превышает 15

data[, new := c(NA,diff.difftime(Start))][, new_id := cumsum(c(1, abs(na.omit(new)) >= 15))]

, что дает

    id               Start      new new_id
 1:  1 2019-03-01 09:15:36       NA      1
 2:  2 2019-01-01 08:00:00 -5102136      2
 3:  2 2019-01-01 08:00:10       10      2
 4:  2 2019-01-01 08:00:30       20      3
 5:  3 2019-01-01 08:00:00      -30      4
 6:  3 2019-01-01 08:00:10       10      4
 7:  3 2019-01-01 08:00:20       10      4
 8:  3 2019-01-01 08:00:40       20      5
 9:  3 2019-01-01 08:00:50       10      5
10:  3 2019-01-01 08:01:01       11      5

Вы можете удалить любые ненужные столбцы как обычно

0 голосов
/ 16 января 2020

Мне любопытно, будет ли работать для ваших данных следующее:

library(data.table)

dt[
  ,
  session := frollapply(Start, 2, function(x) diff(x) >= 15, fill = 1),
  by = 'id'
][
  ,
  session := cumsum(session)
]

#     id               Start session
#  1:  1 2019-03-01 09:15:36       1
#  2:  2 2019-01-01 08:00:00       2
#  3:  2 2019-01-01 08:00:10       2
#  4:  2 2019-01-01 08:00:30       3
#  5:  3 2019-01-01 08:00:00       4
#  6:  3 2019-01-01 08:00:10       4
#  7:  3 2019-01-01 08:00:20       4
#  8:  3 2019-01-01 08:00:40       5
#  9:  3 2019-01-01 08:00:50       5
# 10:  3 2019-01-01 08:01:01       5

Данные:

dt = data.table(
  id = c(1, 2, 2, 2, 3, 3, 3, 3 , 3, 3),
  Start = as.POSIXct(
    c(
      "2019-03-01 09:15:36",
      "2019-01-01 08:00:00",
      "2019-01-01 08:00:10",
      "2019-01-01 08:00:30",
      "2019-01-01 08:00:00",
      "2019-01-01 08:00:10",
      "2019-01-01 08:00:20",
      "2019-01-01 08:00:40",
      "2019-01-01 08:00:50",
      "2019-01-01 08:01:01"
    ),
    ,
    format = "%Y-%m-%d %H:%M:%S"
  )
)
...