подсчет последовательных дат R

#r #date #time #lag #lead

Вопрос:

Как проверить в столбце, отличаются ли даты одна от другой

Ответ №1:

С tidyverse помощью вы можете group_by id как использовать, так и использовать второй идентификатор id2 , который сгруппирует строки вместе, разделенные разницей в один день. Затем столбец «количество последовательных дней» будет включать разницу между last датой и first date (или нулем, если не first date ).

 library(tidyverse)  data %gt;%  mutate(date = as.Date(date, format = "%m-%d-%Y")) %gt;%  arrange(id, date) %gt;%  group_by(id) %gt;%  group_by(id2 = cumsum(c(T, diff(date) gt; 1)), .add = T) %gt;%  mutate(num_con_days = ifelse(date == first(date), last(date) - date   1, 0)) %gt;%  ungroup %gt;%  select(-id2)  

Выход

 day id date num_con_days  lt;dblgt; lt;dblgt; lt;dategt; lt;dblgt;  1 1 10 2021-01-01 1  2 3 10 2021-01-03 4  3 4 10 2021-01-04 0  4 5 10 2021-01-05 0  5 6 10 2021-01-06 0  6 1 24 2021-01-01 2  7 2 24 2021-01-02 0  8 4 24 2021-01-04 3  9 5 24 2021-01-05 0 10 6 24 2021-01-06 0  

Изменить: Используя другой пример с переименованными именами столбцов, у вас есть следующие данные.рамка:

 id day num_consecutive_days 1 1 2021-01-02 1 2 2 2021-01-02 1 3 2 2021-01-05 2 4 2 2021-01-06 0 5 2 2021-01-12 1 6 3 2021-01-01 2 7 3 2021-01-02 0 8 3 2021-01-04 1 9 3 2021-01-11 1 10 4 2021-01-01 1  

Здесь вы day находитесь в формате Год-Месяц-День (поэтому при преобразовании в дату вам не нужно указывать отдельный формат).

Кроме того, вам нужно будет убедиться, что имена ваших столбцов совпадают и соответствуют day друг другу . Смотрите ниже аналогичный код — он должен совпадать с вашим желаемым результатом.

 df %gt;%  mutate(day = as.Date(day)) %gt;%  arrange(id, day) %gt;%  group_by(id) %gt;%  group_by(id2 = cumsum(c(T, diff(day) gt; 1)), .add = T) %gt;%  mutate(num_con_days = ifelse(day == first(day), last(day) - day   1, 0)) %gt;%  ungroup %gt;%  select(-id2)  

Выход

 id day num_consecutive_days 1 1 2021-01-02 1 2 2 2021-01-02 1 3 2 2021-01-05 2 4 2 2021-01-06 0 5 2 2021-01-12 1 6 3 2021-01-01 2 7 3 2021-01-02 0 8 3 2021-01-04 1 9 3 2021-01-11 1 10 4 2021-01-01 1  

Комментарии:

1. Спасибо! не могли бы вы объяснить логику, лежащую в основе оператора ifelse в функции mutate? Я немного запутался в том, как это интерпретировать

2. Ifelse позволяет вам проверить, изменяете ли вы — в пределах группы — первую строку в этой группе. Если это первая строка, то значение устанавливается равным количеству последовательных дат. Если это не первая строка в группе, то значение равно нулю. Это дает желаемый результат с нулями для последовательных дат (кроме первой).

3. Я снова попробовал ваш код, и, похоже, результат не тот же самый. Я получаю только четыре столбца (день, идентификатор, дата, num_con_days_2), и он неправильно считает последовательные дни

4. Я отредактировал ответ и добавил arrange . Ваш пост включает arrange в себя by user (которого нет в ваших данных примера — вы имели в виду id ?). Похоже, что это дает результат, аналогичный тому, который вы хотите получить. Одно из отличий заключается в том, что желаемый результат не сортируется по id .

5. @JaneMiller Если вы не получаете тот же результат — какой результат вы получаете? Можете ли вы описать это подробнее? Если вы «получаете только четыре столбца», каких столбцов вам не хватает? В желаемом выводе в вашем примере у вас есть только 4 столбца данных.