Совокупные идентификаторы заданного типа min_date и max_date меняются со временем - PullRequest
2 голосов
/ 20 мая 2019

Я пытаюсь агрегировать дату по типу по времени, учитывая изменения, произошедшие в течение всего периода времени для локальных min_date и max_date для каждого интервала времени.

id  type    date
1   A       2019-01-01
1   A       2019-01-02
1   B       2019-01-03
1   B       2019-01-04
2   A       2019-01-01
2   A       2019-01-02
2   B       2019-01-03
2   A       2019-01-04

Код:

df <- data.frame(id = c(1, 1, 1, 1, 2, 2, 2, 2), type = c("A", "A", "B", "B", "A", "A", "B", "C"), date = as.Date(c("2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04", "2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04"), "%Y-%m-%d"))

Результат, который я пытаюсь получить:

id  type    min_date    max_date
1   A       2019-01-01  2019-01-02
1   B       2019-01-03  2019-01-04
2   A       2019-01-01  2019-01-02
2   B       2019-01-03  2019-01-03
2   A       2019-01-04  2019-01-04

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

library(dplyr)
df_changes <- df %>% group_by(id, type) %>% summarise(listings = n(), min_date = min(date), max_date = max(date))

Ответы [ 3 ]

2 голосов
/ 20 мая 2019

Вы можете сделать:

df %>%
 group_by(rleid = with(rle(type), rep(seq_along(lengths), lengths))) %>%
 summarise(min_date = min(date),
           max_data = max(date),
           id = first(id),
           type = first(type)) %>%
 ungroup() %>%
 select(-rleid)

  min_date   max_data      id type 
  <date>     <date>     <dbl> <chr>
1 2019-01-01 2019-01-02     1 A    
2 2019-01-03 2019-01-04     1 B    
3 2019-01-01 2019-01-02     2 A    
4 2019-01-03 2019-01-03     2 B    
5 2019-01-04 2019-01-04     2 C 

Или:

df %>%
 group_by(rleid = with(rle(type), rep(seq_along(lengths), lengths)), id, type) %>%
 summarise(min_date = min(date),
           max_data = max(date)) %>%
 ungroup() %>%
 select(-rleid)

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

df <- data.frame(id = c(1, 1, 1, 1, 2, 2, 2, 2), type = c("A", "A", "B", "B", "A", "A", "B", "C"), date = as.Date(c("2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04", "2019-01-01", "2019-01-02", "2019-01-03", "2019-01-04"), "%Y-%m-%d"),
                  stringsAsFactors = FALSE)
1 голос
/ 20 мая 2019

Вот вариант с использованием data.table

library(data.table)
setDT(df)[, as.list(range(date)) , .(id, type, grp = rleid(type))][, grp := NULL][]
#  id type         V1         V2
#1:  1    A 2019-01-01 2019-01-02
#2:  1    B 2019-01-03 2019-01-04
#3:  2    A 2019-01-01 2019-01-02
#4:  2    B 2019-01-03 2019-01-03
#5:  2    C 2019-01-04 2019-01-04
0 голосов
/ 20 мая 2019

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

df %>%
  # New code: count how many times type is different from the prior line
  mutate(new_period = cumsum(type != lag(type,default = ""))) %>%
  group_by(id, type, new_period) %>% 

  # Orig code
  summarise(listings = n(), min_date = min(date), max_date = max(date))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...