R: групповые даты, которые находятся рядом друг с другом - PullRequest
1 голос
/ 11 февраля 2020

У меня есть неправильная последовательность дат (лет).

В частности, за 2004 годом следует 2005, отсутствует 2006, присутствует 2007, затем следует 2008, затем последовательность отсутствует до 2014 года.

# data input
df_in <- 
  data.frame(seq = c(2004L, 2005L, 2007L, 2008L, 2014L, 2015L, 2016L))

# desired result
df_out <- 
  data.frame(df_in, grp = c(1L, 1L, 2L, 2L, 3L, 3L, 3L))

   seq grp
1 2004   1
2 2005   1
3 2007   2
4 2008   2
5 2014   3
6 2015   3
7 2016   3

Я хотел бы найти способ генерировать группы лет, которые находятся рядом друг с другом. Таким образом, группа 1 будет содержать годы 2004 и 2005, группа 2 года 2007 и 2008 и группа 3 года с 2014 по 2016 год.

Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

1 голос
/ 11 февраля 2020

Как насчет:

df_in$group = 1 + c(0, cumsum(ifelse(diff(df_in$seq) > 1, 1, 0)))

Идея здесь заключается в том, что diff вычисляет лаговую разницу. Когда его больше 1, мы добавляем его в группу. cumsum вычисляет кумулятивную сумму тех раз, когда мы столкнулись с разрывом, или новой группой. c(0, есть, потому что вывод diff на один короче наших данных, и нам нужно значение для первого элемента. Наконец, 1 + только для оптики, поэтому первая группа - 1 вместо 0.

> df_in$group 
[1] 1 1 2 2 3 3 3
1 голос
/ 11 февраля 2020
cumsum(c(1, diff(df_in$seq)) != 1) + 1
[1] 1 1 2 2 3 3 3
0 голосов
/ 11 февраля 2020

Это лучшее, что я мог придумать. Но было бы здорово, если бы у кого-то было более элегантное решение:

df_in <- data.frame(seq = c(2004L, 2005L, 2007L, 2008L, 2014L, 2015L, 2016L))

Определить максимальное расстояние между элементами в группе:

max_range_within_group <- 1

Рассчитать существующее расстояния:

diffs <- df_in$seq[-1] - df_in$seq[-length(df_in$seq)]

Итерируйте расстояния между желобами и проверьте, находятся ли они в пределах «разрешенного» расстояния, или увеличьте grp на 1:

grp <- 1
for (diff in diffs) {
  nextGrp <- if (diff <= max_range_within_group) {
    grp[length(grp)]
  } else {
    grp[length(grp)] + 1
  }
  grp <- c(grp, nextGrp)
}

Привязка grp к data.frame:

df_in$grp <- grp

Возвращает:

   seq grp
1 2004   1
2 2005   1
3 2007   2
4 2008   2
5 2014   3
6 2015   3
7 2016   3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...