Для работы с временными рядами в соответствии с принципами организации и хранения “опрятных данных” (“tidy data”) и использовании инструментов из группы tidyverse
группа исследователей под руководством проф. Роба Хиндмана (Rob Hyndman) разработала новый формат объекта tsibble, реализованный в пакете tsibble.
Временной ряд можно представить себе как список чисел (измерений) вместе с некоторой информацией о том, когда эти числа были записаны (индекс). Эта информация может быть сохранена как tsibble
объект в R.Он характеризуется следующими свойствами:
- данные хранятся в табличном виде;
- в таблице должны присутствовать как минимум два столбца — со значениями наблюдаемой во времени количественной переменной и с упорядоченными по возрастанию (т.е. от прошлого к будущему) временными отметками (столбец с временными отметками называется индексирующим —
index
; - кроме того, в таблицу могут входить одна или несколько группирующих переменных (
key
) — значения этих переменных указывают на принадлежность каждого наблюдения к соответствующему временному ряду; - любое наблюдение в таблице можно уникально идентифицировать по сочетанию значений индексирующей и группирующих переменных.
Создать такой объект можно с помощью функции tsibble :
month_index <- seq.Date(from = as.Date("2018-01-01"),
to = as.Date("2019-12-01"),
by = "month")
rev <- c(21520,20356,25922,31087,30442,27584,22787,21281,28781,32347,44638,50456,
26951,27145,28687,32506,28532,29739,21817,29583,27777,34017,40004,44561)
y <- tsibble(Month = yearmonth(month_index), Observation = rev, index = Month)
y
# A tsibble: 24 x 2 [1M]
Month Observation
<mth> <dbl>
1 2018 янв 21520
2 2018 фев 20356
3 2018 мар 25922
4 2018 апр 31087
5 2018 май 30442
6 2018 июн 27584
7 2018 июл 22787
8 2018 авг 21281
9 2018 сен 28781
10 2018 окт 32347
# ... with 14 more rows
В этом примере был создан объект tsibble, представляющий месячные продажи в магазине с января 2018 по декабрь 2019. «[1M]» в первой строке, указывающее, что это данные за месяц.
В зависимости от частоты наблюдений при создании объекта могут использоваться другие функции класса времени.
Годовой | start:end |
Ежеквартальный | yearquarter() |
Ежемесячно | yearmonth() |
Еженедельно | yearweek() |
Ежедневно | as_date() , ymd() |
Субдневный | as_datetime() |
Для создания объектов класса tsibble
из других объектов данных служит функция as_tsibble()
, которая имеет следующие аргументы:
x
— объект с данными, подлежащий преобразованию в объект класса tsibble
(это может быть, например, числовой вектор, матрица, таблица с данными (data.frame
или tibble
) и др.).index
— переменная с временными отметками (указывается без кавычек). Допускается использование временных отметок на шкале от наносекунд до года.key
— одна или несколько группирующих, или ключевых, переменных, которые уникально определяют каждый хранящийся в таблице временной ряд. Названия переменных указываются без кавычек и объединяются с помощью функции конкатенации c()
. По умолчанию этот аргумент равен NULL
, т.е. предполагается, что группирующих переменных в таблице нет.regular
— логический аргумент, который указывает на регулярность учета хранящихся в таблице наблюдений. Значение TRUE
(принято по умолчанию) предполагает, что учет выполнялся с одинаковым интервалом (например, каждую минуту, час, день, и т.п.).validate
— логический аргумент (по умолчанию равен TRUE
), позволяющий выполнить проверку уникальности каждого наблюдения по сочетанию значений переменных index
и key.
Если вы уверены, что каждое наблюдение уникально, то такую проверку можно отключить (FALSE
) — это приведет к более быстрому выполнению команды as_tsibble()
в случае с большими наборами данных..drop
— логический аргумент, позволяющий исключить из таблицы “пустые” временные ряды, т.е. такие сочетания значений группирующих переменных, для которых значения x
отсутствуют.
Рассмотрим как можно сделать объект tsibble из датафрейма, у нас есть данные по 44 магазинам по месяцам с января 2015 по декабрь 2019 с выручками и заработной платой персонала
> shop_rev
# A tibble: 2,640 x 4
ds shop rev wage
<date> <chr> <dbl> <dbl>
1 2015-01-01 Sh1 98046 8824
2 2015-01-01 Sh2 46233 3699
3 2015-01-01 Sh3 17023 1532
4 2015-01-01 Sh4 43381 3470
5 2015-01-01 Sh5 49419 4942
6 2015-01-01 Sh6 29154 2624
7 2015-01-01 Sh7 46008 5521
8 2015-01-01 Sh8 45281 3622
9 2015-01-01 Sh9 50929 5602
10 2015-01-01 Sh10 52140 6257
# ... with 2,630 more rows
Сделаем из него объект tsibble
t_shop_rev <-shop_rev %>%
mutate(ds = yearmonth(ds)) %>%
as_tsibble(key = shop,index = ds)
t_shop_rev
# A tsibble: 2,640 x 4 [1M]
# Key: shop [44]
ds shop rev wage
<mth> <chr> <dbl> <dbl>
1 2015 янв Sh1 98046 8824
2 2015 фев Sh1 70041 7705
3 2015 мар Sh1 102630 12316
4 2015 апр Sh1 103127 10313
5 2015 май Sh1 115185 13822
6 2015 июн Sh1 90927 10911
7 2015 июл Sh1 84353 9279
8 2015 авг Sh1 93958 9396
9 2015 сен Sh1 95731 9573
10 2015 окт Sh1 180711 18071
# ... with 2,630 more rows
Ключ в объекте tsibble может состоять из нескольких полей, допустим у нас есть датафрейм с теми же месячными выручками 44 магазинов, но разделенных по полу
> shop_rev_sex
# A tibble: 5,280 x 4
ds shop sex y
<date> <chr> <chr> <dbl>
1 2015-01-01 Sh1 male 40199
2 2015-01-01 Sh2 male 24966
3 2015-01-01 Sh3 male 8682
4 2015-01-01 Sh4 male 23426
5 2015-01-01 Sh5 male 27674
6 2015-01-01 Sh6 male 17492
7 2015-01-01 Sh7 male 25765
8 2015-01-01 Sh8 male 24905
9 2015-01-01 Sh9 male 26483
10 2015-01-01 Sh10 male 27113
# ... with 5,270 more rows
Также сделаем из него объект tsibble
t_shop_rev_sex <-shop_rev_sex %>%
mutate(ds = yearmonth(ds)) %>%
as_tsibble(key = c(shop,sex),index = ds)
t_shop_rev_sex
# A tsibble: 5,280 x 4 [1M]
# Key: shop, sex [88]
ds shop sex y
<mth> <chr> <chr> <dbl>
1 2015 янв Sh1 female 57847
2 2015 фев Sh1 female 35021
3 2015 мар Sh1 female 48236
4 2015 апр Sh1 female 45376
5 2015 май Sh1 female 57592
6 2015 июн Sh1 female 43645
7 2015 июл Sh1 female 40489
8 2015 авг Sh1 female 41342
9 2015 сен Sh1 female 42122
10 2015 окт Sh1 female 81320
# ... with 5,270 more rows
Работа с tsibble объектами
Для работы с объектами tsibble можно использовать функции select(), которая
позволяет выбрать определенные столбцы, в то время как с filter()
можно выбрать определенные строки.
t_shop_rev %>%
filter(shop=="Sh1") %>%
select(ds,shop, rev)
# A tsibble: 60 x 3 [1M]
# Key: shop [1]
ds shop rev
<mth> <chr> <dbl>
1 2015 янв Sh1 98046
2 2015 фев Sh1 70041
3 2015 мар Sh1 102630
4 2015 апр Sh1 103127
5 2015 май Sh1 115185
6 2015 июн Sh1 90927
7 2015 июл Sh1 84353
8 2015 авг Sh1 93958
9 2015 сен Sh1 95731
10 2015 окт Sh1 180711
# ... with 50 more rows
Еще одна полезная функция - summarise()
объединять данные по ключам. Например, мы можем рассчитать общую выручку в месяц независимо от ключей shop или sex.
t_shop_rev_sex %>%
filter(shop=="Sh1") %>%
select(ds, shop, sex, y) %>%
summarise(TotalRev = sum(y))
A tsibble: 60 x 2 [1M]
ds TotalRev
<mth> <dbl>
1 2015 янв 98046
2 2015 фев 70042
3 2015 мар 102630
4 2015 апр 103127
5 2015 май 115184
6 2015 июн 90927
7 2015 июл 84353
8 2015 авг 93959
9 2015 сен 95732
10 2015 окт 180711
# ... with 50 more rows
Для отбора по периодам используется функция filter_index
#По февраль 2015
t_shop_rev %>%
filter(shop=="Sh1") %>%
filter_index(~"2015-02")
#с января по июнь 2015
t_shop_rev %>%
filter(shop=="Sh1") %>%
filter_index("2015-01"~"2015-06")
# с августа 2016 и до конца
t_shop_rev %>%
filter(shop=="Sh1") %>%
filter_index("2016-08" ~ .)
# интервал периодов
t_shop_rev %>%
filter(shop=="Sh1") %>%
filter_index(~"2015-02", "2015-08" ~ "2015-09", "2015-12" ~ "2016-02")
# 2015 год
t_shop_rev %>%
filter(shop=="Sh1") %>%
filter_index("2015")
Агрегирование наблюдений
Под агрегирование при работе с временными рядами является понимается расчет показателей за определенный календарный период (например, средние или суммарные значения за день, неделю, месяц, квартал и т.п.). В пакете для таких вычислений используется связка из двух функций: index_by()
и summarise()
. Первая из этих функций входит в состав пакета tsibble
и аналогична group_by()
из пакета dplyr
. Как следует из ее названия, index_by()
группирует данные по заданному пользователем периоду времени. Для указания необходимого периода применяются такие функции из пакета tsibble
, как yearweek()
(неделя), yearmonth()
(месяц) и yearquarter()
(квартал). Кроме того, можно также использовать базовую as.Date()
и многие функции из пакета lubridate
. Вторая функция из указанной выше связки — summarise()
— входит в состав пакета dplyr
и служит для вычисления необходимых агрегированных величин.
В качестве примера рассчитаем среднюю квартальную выручку и заработную пату по магазинам а также общее число наблюдений, учтенных в каждом квартале исследованного периода:
t_shop_rev_qv <- t_shop_rev %>%
group_by_key() %>%
index_by(year_qv = ~ yearquarter(.)) %>%
summarise(
avg_rev = mean(rev),
avg_wage = mean(wage),
n = n()
)
t_shop_rev_qv
# A tsibble: 880 x 5 [1Q]
# Key: shop [44]
shop year_qv avg_rev avg_wage n
<chr> <qtr> <dbl> <dbl> <int>
1 Sh1 2015 Q1 90239 9615 3
2 Sh1 2015 Q2 103080. 11682 3
3 Sh1 2015 Q3 91347. 9416 3
4 Sh1 2015 Q4 175729. 17582 3
5 Sh1 2016 Q1 109201 10649 3
6 Sh1 2016 Q2 102430 11007. 3
7 Sh1 2016 Q3 99987 9901. 3
8 Sh1 2016 Q4 169136 16866. 3
9 Sh1 2017 Q1 87836. 9136 3
10 Sh1 2017 Q2 101203 10436. 3
# ... with 870 more rows
Перед вычислением агрегированных показателей сначала группируются данные по каждому магазину с помощью функции group_by_key()
и так как в этом наборе данных есть только одна группирующая переменная (shop) и она была задана при создании таблицы, то при вызове group_by_key()
не было необходимости указывать эту группирующую переменную в явном виде.
Комментариев нет:
Отправить комментарий