dat %>% mutate(numb=as.integer(gsub("^[0-9]*-","",bill_date))) %>%
group_by(id, card_id) %>% summarize(maxc=numb[sum(numb==numb[1]:(numb[n()]+numb[1]-1))])
Результат:
# A tibble: 4 x 3
# Groups: id [?]
id card_id maxc
<chr> <chr> <int>
1 Adam 0001 2
2 Adam 0002 3
3 Bob 0003 3
4 Bob 0004 5
Объяснение: mutate
создает столбец только с номерами месяцев.Затем мы группируем по id
и card_id
и создаем сводку, которая сравнивает вектор чисел в группе с вектором равной длины, который начинается с первого месяца в группе до последнего, суммирует все случаи, когдаответ «ИСТИНА», а затем возвращает число в строке, соответствующее этой сумме (т. е. последнее число, которое было последовательным).
Примечание: это будет прервано, когда bill_date охватывает более одного года непрерывно.
Хорошо, я пытался придумать, как обойти эту проблему с многолетним охватом случаев, и я нашел это решение.
Во-первых, новые данные, содин случай, охватывающий два года:
dat = data.frame(id = c(rep("Adam", 5), rep("Bob", 10)),
card_id = c(rep("0001", 2), rep("0002", 3), rep("0003", 5), rep("0004", 5)),
bill_date = c("2017-01", "2017-02",
"2017-12", "2018-01", "2018-03",
"2017-01", "2017-02", "2017-03", "2017-05", "2017-06",
"2017-01", "2017-02", "2017-03", "2017-04", "2017-05"), stringsAsFactors = F)
Теперь мы изменим дату счета на фактические даты и используем cut.POSIXt
, чтобы создать последовательность месяцев, и применим предыдущее решение к этой последовательности:
dat$monthseq<-cut.POSIXt(as.POSIXct(paste0(dat$bill_date,"-01")),breaks="month",labels=FALSE)
dat%>%
group_by(id, card_id) %>%
summarize(maxc=bill_date[sum(monthseq==monthseq[1]:(monthseq[n()]))])
Результат:
# A tibble: 4 x 3
# Groups: id [?]
id card_id maxc
<chr> <chr> <chr>
1 Adam 0001 2017-02
2 Adam 0002 2018-01
3 Bob 0003 2017-03
4 Bob 0004 2017-05