Группировка 1-й и последней даты определенной недели - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть датафрейм, содержащий даты 2015-2019. Это выглядит примерно так:

date       | week | value
2016-01-01 | 53   | 3
2016-01-02 | 53   | 7
2016-01-03 | 53   | 1
2016-01-04 | 1    | 9
2016-01-05 | 1    | 4
2016-01-06 | 1    | 8
2016-01-07 | 1    | 4
2016-01-08 | 1    | 5
2016-01-09 | 1    | 6
2016-01-10 | 1    | 20
.
.
.
2016-12-31 | 52   | 31
2017-01-01 | 52   | 2
2017-01-02 | 52   | 49

Выше приведен фрагмент кода с 1-м столбцом, содержащим все отдельные даты 2015–2019 гг., А второй столбец - isoweek (с использованием lubridate), которому принадлежит дата. к. Я пытаюсь получить и сгруппировать даты таким образом, чтобы они отображали только первую дату и последнюю дату каждого isoweek, причем одна из них выглядит так:

2016-01-04 | 1    | 9
2016-01-10 | 1    | 20

Это просто, используя dplyr group_by ( год и isoweek), а затем фильтрация по номерам строк. Но проблема, с которой я столкнулся здесь, заключается в том, что некоторые из последних недель года переходят на следующий год, например 52-ю неделю 2016 года. В этом случае я не могу группировать по годам, а затем по неделям, чтобы получить первую и последнюю строку с тех пор У меня будет два комплекта недели 52 в конце 2016 года и в начале 2017 года. Есть ли способ получить первый и последний ряд каждой недели без необходимости смотреть на год. то есть фильтрация только для первой записи и последней записи каждой недели, отмечая здесь, что существует несколько недель 1 с, 2 с 3 с и т. д. из разных лет. В идеале это должно выкинуть что-то вроде этого:

date       | week | value
2016-01-01 | 53   | 3
2016-01-03 | 53   | 1
2016-01-04 | 1    | 9
2016-01-10 | 1    | 20
.
.
.
2016-12-31 | 52   | 31
2017-01-02 | 52   | 49
2017-01-03 | 1    | 34
2017-01-09 | 1    | 2

Ответы [ 2 ]

0 голосов
/ 19 апреля 2020

Мы можем сравнить week с предыдущим значением, используя lag, и взять 1-е и последнее значение из этой новой группы.

library(dplyr)

df %>%
  group_by(grp = cumsum(week != lag(week, default = first(week)))) %>%
  slice(1, n())
0 голосов
/ 19 апреля 2020

Один из подходов заключается в создании нового столбца id для группировки

library(data.table)
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:data.table':
#> 
#>     hour, isoweek, mday, minute, month, quarter, second, wday, week,
#>     yday, year
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union

dt <- data.table(date = seq(ymd(20160101),ymd(20191231),"days"),value=runif(1461,0,10))


dt[,isoweek:=isoweek(date)]

dt[,id:=paste0(rleid(isoweek),"-",isoweek)]

dt[,.SD[c(1,.N),],by=.(id)]
#>          id       date    value isoweek
#>   1:   1-53 2016-01-01 7.231343      53
#>   2:   1-53 2016-01-03 8.732023      53
#>   3:    2-1 2016-01-04 9.292968       1
#>   4:    2-1 2016-01-10 8.502751       1
#>   5:    3-2 2016-01-11 9.123189       2
#>  ---                                   
#> 416: 208-51 2019-12-22 7.619993      51
#> 417: 209-52 2019-12-23 4.538770      52
#> 418: 209-52 2019-12-29 6.318457      52
#> 419:  210-1 2019-12-30 4.570501       1
#> 420:  210-1 2019-12-31 7.968364       1

dt[,.SD[c(1,.N),],by=.(id)][id=="53-52",]
#>       id       date    value isoweek
#> 1: 53-52 2016-12-26 5.570343      52
#> 2: 53-52 2017-01-01 4.577057      52

, созданного в 2020-04-19 пакетом Представления (v0.3.0)

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