Свернуть в зависимости от состояния - PullRequest
0 голосов
/ 04 февраля 2019

Этот вопрос похож на вопрос, уже опубликованный несколько дней назад, Свернуть строки от 0 до 0

Новый поворот, который отличается от предыдущего вопроса, заключается в следующем: какмы сворачиваем строки по Id только для тех строк, где разное время меньше или равно 60.

Например, используя тот же набор данных

Incident.ID..                date           product
INCFI0000029582     2014-09-25 08:39:45     foo
INCFI0000029582     2014-09-25 08:39:45     foo
INCFI0000029582     2014-09-25 08:39:48     bar 
INCFI0000029582     2014-09-25 08:40:44     foo
INCFI0000029582     2014-10-10 23:04:00     foo
INCFI0000029587     2014-09-25 08:33:32     bar
INCFI0000029587     2014-09-25 08:34:41     bar
INCFI0000029587     2014-09-25 08:35:24     bar
INCFI0000029587     2014-10-10 23:04:00     foo


df <- structure(list(Incident.ID.. = c("INCFI0000029582", "INCFI0000029582","INCFI0000029582", 
"INCFI0000029582", "INCFI0000029582", "INCFI0000029587", "INCFI0000029587", 
"INCFI0000029587", "INCFI0000029587"), date = c("2014-09-25 08:39:45","2014-09-25 08:39:45", 
"2014-09-25 08:39:48", "2014-09-25 08:40:44", "2014-10-10 23:04:00", 
"2014-09-25 08:33:32", "2014-09-25 08:34:41", "2014-09-25 08:35:24", 
"2014-10-10 23:04:00"), product = 
c("foo","foo","bar","foo","foo","bar","bar","bar","foo")), 
class = "data.frame", row.names = c(NA, 
-L))

Это вычисляет разницу во времени по ID

 library(dplyr)
 library(lubridate)
 df1 <- df %>%
  group_by(Incident.ID..) %>%
  arrange(ymd_hms(date)) %>%
  mutate(diff = c(0, diff(ymd_hms(date))))

Что приводит к этому новому различию столбца, как показано ниже

Incident.ID..   date                 product    diff
INCFI0000029582 2014-09-25 08:39:45  foo        0
INCFI0000029582 2014-09-25 08:39:45  foo        0
INCFI0000029582 2014-09-25 08:39:48  bar        3
INCFI0000029582 2014-09-25 08:40:44  foo        56
INCFI0000029582 2014-10-10 23:04:00  foo        1347796
INCFI0000029587 2014-09-25 08:33:32  bar        0
INCFI0000029587 2014-09-25 08:34:41  bar        69
INCFI0000029587 2014-09-25 08:35:24  bar        43
INCFI0000029587 2014-10-10 23:04:00  foo        1348116

Теперь только сворачиваются строки на Incident.ID.., где разница во времени меньше или равна 60, т.е.1017 * должен привести к окончательному набору данных, подобному этому

 Incident.ID..     DateMin              DateMax              product      diff_collapse
 INCFI0000029582   2014-09-25 08:39:45  2014-09-25 08:40:44  foo,bar,foo  0,0,3,56
 INCFI0000029582   2014-09-25 08:40:44  2014-10-10 23:04:00  foo          1347796
 INCFI0000029587   2014-09-25 08:33:32  2014-09-25 08:34:41  bar          0
 INCFI0000029587   2014-09-25 08:34:41  2014-09-25 08:35:24  bar,bar      69,43
 INCFI0000029587   2014-09-25 08:35:24  2014-10-10 23:04:00  foo          1348116

Нужна помощь в создании такого свернутого набора данных.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Я бы предложил создать новую переменную группировки.Я получил желаемый результат, например, так:

df1 <- df %>%
  group_by(Incident.ID..) %>%
  arrange(ymd_hms(date)) %>%
  mutate(diff = c(0, diff(ymd_hms(date)))) %>%
  ungroup() %>%
  arrange(Incident.ID.., date) %>%
  mutate(group = cumsum(diff > 60 | diff == 0)) %>%
  group_by(group) %>%
  summarise(DateMin = min(date), 
            DateMax = max(date), 
            diff_collapse = toString(diff),
            product = toString(product))

Я в основном решаю, с какой строки новая группа должна начинаться с условия diff > 60 | diff == 0: diff > 60, потому что это условие свертывания и diff == 0потому что тогда начинается новый инцидент.Вы также можете написать Incident.ID.. != lag(Incident.ID..).Заключение в cumsum увеличивает счетчик каждый раз, когда начинается новая группа.

Сначала важно ungroup, в противном случае cumsum работает только в группе.

0 голосов
/ 04 февраля 2019

Вам нужен столбец группировки, который соответствует вашим потребностям:

... %>% mutate(
  grp = ifelse(diff <= 60,
               paste0(Incident.ID.., "origin"), 
               paste0(Incident.ID.., diff)
  ))

Это создает группировку, которая одинакова (в пределах Incident.ID..) для строк, где разница меньше 60, и уникальна в противном случае,(Предполагается, что diff является уникальным --- если вы можете иметь дублирующиеся различия больше 60, используйте row_number() вместо diff в paste, чтобы убедиться, что оно уникально.) Используйте это в качестве столбца группировки для вашегосвернуть код.

...