Как проверить непрерывность с учетом возможных пробелов в датах - PullRequest
0 голосов
/ 21 января 2019

У меня большой фрейм данных с датами, и мне нужно непрерывно проверять первую дату следующим образом:

ID   ID_2  END         BEG
1    55    2017-06-30  2016-01-01
1    55    2015-12-31  2015-11-12  --> Gap (required date)
1    88    2008-07-26  2003-02-24
2    19    2014-09-30  2013-05-01
2    33    2013-04-30  2011-01-01  --> Not Gap (overlapping)
2    19    2012-12-31  2011-01-01
2    33    2010-12-31  2008-01-01
2    19    2007-12-31  2006-01-01
2    19    2005-12-31  1980-10-20  --> No actual Gap(required date)

Как показано, не все даты перекрываются, и мне нужновернуть по идентификатору (не ID_2) дату появления первого разрыва (в обратном направлении во времени).Я пытался использовать для, но это очень медленно (dataframe имеет 150 тыс. Строк).Я возился с dplyr и mutate следующим образом:

df <- df%>%
  group_by(ID)%>%
  mutate(END_lead = lead(END))

df$FLAG <- df$BEG - days(1) == df$END_lead

df <- df%>%
 group_by(ID)%>%
 filter(cumsum(cumsum(FLAG == FALSE))<=1)

Но этот набор инструкций останавливается при первом перекрытии, фильтруя неправильную дату.Я пробовал все, что мог придумать, упорядочивая по убыванию или по возрастанию и используя минимальное и максимальное значения, но не смог найти решение.

Фактический требуемый результат был бы:

ID   ID_2  END         BEG
1    55    2015-12-31  2015-11-12 
2    19    2008-07-26  1980-10-20 

Есть ли способ сделать это, используя dplyr, tidyr и lubridate?

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Возможное решение с использованием dplyr:

library(dplyr)

df %>%
  mutate_at(vars(END, BEG), funs(as.Date)) %>%
  group_by(ID) %>%
  slice(which.max(BEG > ( lead(END) + 1 ) | is.na(BEG > ( lead(END) + 1 ))))

С вашими последними данными это дает:

# A tibble: 2 x 4
# Groups:   ID [2]
     ID  ID_2 END        BEG       
  <int> <int> <date>     <date>    
1     1    55 2015-12-31 2015-11-12
2     2    19 2005-12-31 1980-10-20

То, что делает решение в основном:

  • Изменяет даты на Date формат (без необходимости lubridate);
  • Группы по ID;
  • Выбирает самую высокую строку, которая удовлетворяет вашим критериям, то есть самая высокая строка, которая является либо пробелом (TRUE), либо, если пробела нет, это первая строка (это означает, что при проверке пробела это значение отсутствует) Вот почему is.na(BEG > ( lead(END) + 1 ))).
0 голосов
/ 21 января 2019

Я бы использовал пакет xts, сначала создав объекты xts для каждого имеющегося у вас идентификатора, а затем использовал функции first () и last () для каждого объекта.

https://www.datacamp.com/community/blog/r-xts-cheat-sheet

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