Праца з датамі на мове R (базавыя магчымасці, а таксама пакеты lubridate і timeperiodsR)

Атрымаць бягучую дату ў любой мове праграмавання, аперацыя эквівалентная "Hello world!". Мова R не зяўляецца выключэннем.

У гэтым артыкуле мы разбяромся з тым, як уладкованая праца з датамі ў базавым сінтаксісе мовы R, а таксама разгледзім некалькі карысных пакетаў, якія пашыраюць яго магчымасці пры працы з датамі:

  • lubridate - пакет які дазваляе вырабляць арыфметычныя вылічэнні паміж датамі;
  • timeperiodsR - пакет для працы з часовымі інтэрваламі і іх кампанентамі.

Праца з датамі на мове R (базавыя магчымасці, а таксама пакеты lubridate і timeperiodsR)

Змест

Калі вы цікавіцеся аналізам дадзеных, і ў прыватнасці мовай R, магчыма вам будуць цікавыя мае тэлеграма и YouTube каналы. Большая частка кантэнту якіх прысвечана мове R.

  1. Праца з датамі ў базавым сінтаксісе R
    1.1. Пераўтварэнне тэксту ў дату
    1.2. Выманне кампанентаў даты ў базавым R
  2. Праца з датамі з дапамогай пакета lubridate
    2.1. Пераўтварэнне тэксту ў дату з дапамогай lubridate
    2.2. Выманне кампанентаў дат з дапамогай пакета lubridate
    2.3. Арыфметычныя аперацыі з датамі
  3. Спрошчаная праца з перыядамі, пакет timeperiodsR
    3.1. Часавыя інтэрвалы ў timeperiodsR
    3.2. Фільтраванне вектара дат з дапамогай timeperiodsR
  4. Заключэнне

Праца з датамі ў базавым сінтаксісе R

Пераўтварэнне тэксту ў дату

У базавай R прысутнічае набор функцый для працы з датамі. Мінус базавага сінтаксісу заключаецца ў тым, што рэгістр імёнаў і аргументаў функцый вельмі разрознены, і практычна не мае лагічнай сувязі. Тым не менш, базавыя функцыі мовы трэба ведаць, таму пачнем мы менавіта з іх.

Найбольш часта пры загрузцы дадзеных у R, з csv файлаў, ці іншых крыніц, вы атрымліваеце дату ў выглядзе тэксту. Для таго, каб прывесці гэты тэкст да правільнага тыпу дадзеных выкарыстоўвайце функцыю as.Date().

# создаём текстовый вектор с датами
my_dates <- c("2019-09-01", "2019-09-10", "2019-09-23")

# проверяем тип данных
class(my_dates)

#> [1] "character"

# преобразуем текст в дату
my_dates <- as.Date(my_dates)

# проверяем тип данных
class(my_dates)

#> [1] "Date"

Па змаўчанні as.Date() прымае дату ў двух фарматах: ГГГГ-ММ-ДД або ГГГГ/ММ/ДД.
Калі ў вашым наборы дадзеных даты прадстаўлены ў якім-небудзь іншым фармаце, для пераўтварэння можна выкарыстоўваць аргумент format.

as.Date("September 26, 2019", format = "%B %d, %Y")

фармат прымае ў радковым выглядзе аператары якія абазначаюць які-небудзь часавы інтэрвал і яго фармат, найбольш часта выкарыстоўваюцца значэння прыведзены ў табліцы ніжэй:

Фармат
Апісанне

%d
Нумар дня ў месяцы

%a
Абрэвіятура назвы дня тыдня

%A
Поўная назва дня тыдня

%w
Нумар дня тыдня (0-6, дзе 0 гэтая нядзеля)

%m
Двухзначнае абазначэнне месяца (01/12)

%b
Абрэвіятура імя месяца (apr, mar, …)

%B
Поўная назва месяца

%y
Двухзначнае абазначэнне года

%Y
Чатырохзначнае абазначэнне года

%j
Нумар дня ў годзе (001 - 366)

%U
Нумар тыдня ў годзе (00 - 53), пачатак тыдня Нядзеля

%W
Нумар тыдня ў годзе (00 - 53), пачатак тыдня Панядзелак

Адпаведна, "September 26, 2019" гэта – поўная назва месяца, чысло і год. Апісаць гэты фармат даты аператарамі можна так:"%B %d, %Y".

Дзе:

  • %B - Поўная назва месяца
  • %d - Нумар дня ў месяцы
  • %Y - Чатырохзначнае абазначэнне года

Пры апісанні фармату даты важна ўключаць усе дадатковыя сімвалы з вашага радка, напрыклад працяжнік, коскі, кропкі, прабелы і гэтак далей. У маім прыкладзе, "September 26, 2019", пасля даты варта коска, і ў апісанне фармату гэтак жа трэба ставіць коску:"%B %d, %Y".

Бываюць сітуацыі, калі вы атрымліваеце дату не толькі не адпаведную стандартным фарматам (ГГГГ-ММ-ДД або ГГГГ/ММ/ДД), але яшчэ і на мове, які адрозніваецца ад усталяванага ў вашай аперацыйнай сістэме па змаўчанні. Напрыклад, вы загрузілі дадзеныя, дзе дата пазначана вось у такім выглядзе: "Снежань 15, 2019 г.". Перад канвертаваннем гэтага радка ў дату вам неабходна памяняць лакаль.

# Меняем локаль
Sys.setlocale("LC_TIME", "Russian")
# Конвертируем строку в дату
as.Date("Декабрь 15, 2019 г.", format = "%B %d, %Y")

Выманне кампанентаў даты ў базавым R

У базавым R не так шмат функцый якія дазваляюць здабываць якую-небудзь частку даты з аб'екта класа дата.

current_date <- Sys.Date() # текущая дата
weekdays(current_date)     # получить номер дня недели
months(current_date)       # получить номер месяца в году
quarters(current_date)     # получить номер квартала в году

Апроч асноўнага класа аб'ектаў дата у базавым R ёсць яшчэ 2 тыпы дадзеных якія захоўваюць адзнаку часу: POSIXlt, POSIXct. Асноўнае адрозненне гэтых класаў ад дата заключаецца ў тым, што акрамя даты яны захоўваюць час.

# получить текущую дату и время
current_time <- Sys.time()

# узнать класс объекта current_time 
class(current_time)

# "POSIXct" "POSIXt"

Функцыя Sys.time() вяртае бягучую дату і час у фармаце POSIXct. Гэты фармат па сэнсе падобны да UNIXTIME, і захоўвае ў сабе колькасць секунд з моманту пачатку эры UNIX (поўнач (па UTC) з 31 снежня 1969 года на 1 студзеня 1970).

Клас POSIXlt таксама захоўвае ў сабе час і дату, і ўсе іх кампаненты. Таму з'яўляецца аб'ектам з больш складанай структурай, але з якога лёгка атрымаць любы кампанент даты і чакай т.к. па сутнасці POSIXlt гэта спіс.

# Получаем текущую дату и время
current_time_ct <- Sys.time()

# Преобразуем в формат POSIXlt
current_time_lt <- as.POSIXlt(current_time_ct)

# извлекаем компоненты даты и времени
current_time_lt$sec   # секунды
current_time_lt$min   # минуты
current_time_lt$hour  # часы
current_time_lt$mday  # день месяца
current_time_lt$mon   # месяц
current_time_lt$year  # год
current_time_lt$wday  # день недели
current_time_lt$yday  # день года
current_time_lt$zone  # часовой пояс

Пераўтварэнне лікавых і тэкставых дадзеных у фарматы POSIX* ажыццяўляюцца функцыямі as.POSIXct() и as.POSIXlt(). Гэтыя функцыі маюць невялікі набор аргументаў.

  • x - Лік, радок або аб'ект класа дата, які неабходна пераўтварыць;
  • tz - Часавы пояс, па змаўчанні "GMT";
  • format - Апісанне фармату даты ў якім прадстаўлены дадзеныя перадаюцца ў аргумент x;
  • origin - Выкарыстоўваецца толькі пры канвертацыі ліку ў POSIX, у гэты аргумент неабходна перадаць аб'ект даты, і часу ад якога ідзе адлік секунд. Як правіла, выкарыстоўваецца для пераводу з UNIXTIME.

Калі вашы дадзеныя аб даце і часе прадстаўлены ў UNIXTIME, то для іх канвертацыі ў зразумелую, чытэльную дату выкарыстоўвайце наступны прыклад:

# Конвертируем UNIXTIME в читаемую дату 
as.POSIXlt(1570084639,  origin = "1970-01-01")

У origin вы можаце пазначыць любую часовую пазнаку. Напрыклад, калі ў вашых дадзеных дата і час пазначаны як колькасць секунд пачынаючы ад 15 верасня 2019 года 12:15, то для пераўтварэння іх у дату выкарыстоўвайце:

# Конвертируем UNIXTIME в дату учитывая что начало отсчёта 15 сентября 2019 12:15
as.POSIXlt(1546123,  origin = "2019-09-15 12:15:00")

Праца з датамі з дапамогай пакета lubridate

lubridate мабыць самы папулярны пакет для працы з датамі на мове R. Ён дае вам дадаткова яшчэ тры класы.

  • durations - працягласць, г.зн. колькасць секунд паміж двума часовымі пазнакамі;
  • periods - перыяды дазваляюць вырабляць вылічэнні паміж датамі зразумелымі для чалавека інтэрваламі: днямі, месяцамі, тыднямі і гэтак далей;
  • intervals - аб'екты якія прадстаўляюць пачатковы і канчатковы момант часу.

Устаноўка дадатковых пакетаў у мове R ажыццяўляецца стандартнай функцыяй install.packages().

Ўстаноўка пакета lubridate:

install.packages("lubridate")

Пераўтварэнне тэксту ў дату з дапамогай lubridate

Функцыі пакета lubridate значна спрашчаюць працэс канвертавання тэксту ў дату, а таксама дазваляюць вам праводзіць любыя арыфметычныя аперацыі з датамі і часам.

Атрымаць бягучую дату, ці дату і час вам дапамогуць функцыі today() и now().

today() # текущая дата
now()   # текущая дата и время

Для пераўтварэння радка ў дату ў lubridate ёсць цэлае сямейства функцый імёны якіх складаюцца заўсёды з трох літар, і абазначаюць паслядоўнасць кампанентаў даты:

  • y - год
  • m - месяц
  • d - дзень

Спіс функцый для пераўтварэння тэксту ў дату праз lubridate

  • ymd()
  • ydm()
  • mdy()
  • myd()
  • dmy()
  • dym()
  • yq()

Некалькі прыкладаў для пераўтварэння радкоў у даты:

ymd("2017 jan 21")
mdy("March 20th, 2019")
dmy("1st april of 2018")

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

Выманне кампанентаў дат з дапамогай пакета lubridate

Таксама з дапамогай lubridate можна атрымаць любы кампанент з даты:

dt <- ymd("2017 jan 21")

year(dt)  # год
month(dt) # месяц
mday(dt)  # день в месяце
yday(dt)  # день в году
wday(dt)  # день недели

Арыфметычныя аперацыі з датамі

Але, найбольш важны і асноўны функцыянал lubridate заключаецца ў магчымасці вырабляць розныя арыфметычныя аперацыі з датамі.

Акругленне даты ажыццяўляецца трыма функцыямі:

  • floor_date - акругленне да бліжэйшага мінулага часу
  • ceiling_date - акругленне да бліжэйшага будучага часу
  • round_date - акругленне да найбліжэйшага часу

Кожная з гэтых функцый мае аргумент блок, які дазваляе вам паказаць адзінку акруглення: second, minute, hour, day, week, месяц, bimonth, quarter, season, halfyear, year

dt <- ymd("2017 jan 21")

round_date(dt, unit = "month")    # округлить до месяца
round_date(dt, unit = "3 month")  # округлить до 3 месяцев
round_date(dt, unit = "quarter")  # округлить до квартала
round_date(dt, unit = "season")   # округлить до сезона
round_date(dt, unit = "halfyear") # округлить до полугодия

Такім чынам, давайце разбяромся з тым, як атрымаць дату, якая будзе праз 8 дзён пасля бягучай даты і праводзіць розныя іншыя арыфметычныя вылічэнні паміж двума датамі.

today() + days(8)   # какая дата будет через 8 дней
today() - months(2) # какая дата была 2 месяца назад
today() + weeks(12) # какая дата будет через 12 недель
today() - years(2)  # какая дата была 2 года назад

Спрошчаная праца з перыядамі, пакет timeperiodsR.

timeperiodsR - свежы пакет для працы з датамі які быў апублікаваны на CRAN ў верасні 2019 года.

Ўстаноўка пакета timeperiodsR:

install.packages("timeperiodsR")

Асноўнае прызначэнне - хуткае вызначэнне некаторага часовага інтэрвалу адносна зададзенай даты. Напрыклад, з дапамогай яго функцый вы лёгка можаце:

  • Атрымаць мінулы тыдзень, месяц, квартал ці год у R.
  • Атрымаць зададзеную колькасць часавых інтэрвалаў адносна даты, напрыклад мінулыя 4 тыдні.
  • Лёгка здабываць з атрыманага часавага інтэрвалу яго кампаненты: пачатковую і канчатковую дату, колькасць дзён якія трапілі ў інтэрвал, усю паслядоўнасць дат якія ў яго ўваходзяць.

Назва ўсіх функцый пакета timeperiodsR інтуітыўна зразумелыя, і складаюцца з дзвюх частак: кірунак_інтэрвал, дзе:

  • кірунак у якім неабходна рухацца адносна зададзенай даты: last_n, previous, this, next, next_n.
  • часовай інтэрвал для вылічэння перыяду: day, week, month, quarter, year.

Поўны набор функцый:

  • last_n_days()
  • last_n_weeks()
  • last_n_months()
  • last_n_quarters()
  • last_n_years()
  • previous_week()
  • previous_month()
  • previous_quarter()
  • previous_year()
  • this_week()
  • this_month()
  • this_quarter()
  • this_year()
  • next_week()
  • next_month()
  • next_quarter()
  • next_year()
  • next_n_days()
  • next_n_weeks()
  • next_n_months()
  • next_n_quarters()
  • next_n_years()
  • custom_period()

Часавыя інтэрвалы ў timeperiodsR

Гэтыя функцыі карысныя ў выпадках, калі вам неабходна будаваць справаздачы на ​​аснове даных за мінулы тыдзень ці месяц. Каб атрымаць мінулы месяц скарыстайцеся аднайменнай функцыяй previous_month():

prmonth <- previous_month()

Пасля чаго ў вас будзе аб'ект prmonth класа тпр, З якога лёгка можна атрымаць наступныя кампаненты:

  • дату пачатку перыяду, у нашым прыкладзе гэта мінулы месяц
  • дату завяршэння перыяду
  • колькасць дзён якія ўваходзяць у перыяд
  • паслядоўнасць дат якія ўваходзяць у перыяд

Прычым атрымаць кожны з кампанентаў можна рознымі спосабамі:

# первый день периода
prmonth$start
start(prmonth)

# последний день периода
prmonth$end
end(prmonth)

# последовательность дат
prmonth$sequence
seq(prmonth)

# количество дней входящих в период
prmonth$length
length(prmonth)

Таксама вы можаце атрымаць любы з кампанентаў выкарыстоўваючы аргумент частка, які прысутнічае ў кожнай з функцый пакета. Магчымыя значэнні: start, end, sequence, length.

previous_month(part = "start")    # начало периода
previous_month(part = "end")      # конец периода
previous_month(part = "sequence") # последовательность дат
previous_month(part = "length")   # количество дней в периоде

Такім чынам, давайце разгледзім усе аргументы даступныя ў функцыях пакета. timeperiodsR:

  • x - Апорная дата ад якой будзе вылічваць часавы перыяд, па змаўчанні бягучая дата;
  • n - Колькасць інтэрвалаў якія будуць уваходзіць у перыяд, напрыклад 3 папярэднія тыдні;
  • part - Які кампанент аб'екта tpr вам неабходна атрымаць, па змаўчанні all;
  • week_start - Аргумент прысутнічае толькі ў функцыях для працы з тыднямі, і дазваляе задаць нумар дня тыдня які будзе лічыцца яго пачаткам, па змаўчанні пачаткам тыдня з'яўляецца панядзелак, але вы можаце задаць любы з 1 - панядзелак па 7 - нядзелю.

Такім чынам, вы можаце вылічаць любы часавы перыяд адносна бягучай, альбо любой іншай зададзенай даты, прывяду яшчэ некалькі прыкладаў:

# получить 3 прошлые недели
# от 6 октября 2019 года
# начало недели - понедельник
last_n_weeks(x = "2019-10-06", 
             n = 3, 
             week_start = 1)

 Time period: from  9 September of 2019, Monday to 29 September of 2019, Sunday

6 кастрычніка гэтая нядзеля:
Праца з датамі на мове R (базавыя магчымасці, а таксама пакеты lubridate і timeperiodsR)

Нам неабходны перыяд, які адносна 6 кастрычніка возьме 3 папярэднія тыдні. Не ўключаючы тыдзень, у які ўваходзіць само 6 кастрычніка. Адпаведна гэты перыяд з 9 па 29 верасня.

Праца з датамі на мове R (базавыя магчымасці, а таксама пакеты lubridate і timeperiodsR)

# получить месяц отстающий на 4 месяца
# от 16 сентября 2019 года
previous_month(x = "2019-09-16", n = 4)

 Time period: from  1 May of 2019, Wednesday to 31 May of 2019, Friday

У гэтым прыкладзе нас цікавіць месяц, які быў 4 месяцы таму, калі адштурхоўвацца ад 16 верасня 2019 года, адпаведна гэта быў май 2019 года.

Фільтраванне вектара дат з дапамогай timeperiodsR

Для фільтрацыі дат у timeperiodsR ёсць некалькі аператараў:

  • %left_out% - параўноўвае два аб'екты класа tpr, і вяртае значэнне з левага, якія адсутнічаюць у правым.
  • %left_in% - параўноўвае два аб'екты класа tpr, і вяртае даты з левага аб'екта якія ўваходзяць у правы.
  • %right_out% - параўноўвае два аб'екты класа tpr, і вяртае значэнне з правага, якія адсутнічаюць у левым.
  • %right_in% - параўноўвае два аб'екты класа tpr, і вяртае даты з правага аб'екта якія прысутнічаюць у левым.

period1 <- this_month("2019-11-07")
period2 <- previous_week("2019-11-07")

period1 %left_in% period2   # получить даты из period1 которые входят в period2
period1 %left_out% period2  # получить даты из period1 которые не входят в period2
period1 %right_in% period2  # получить даты из period2 которые входят в period1
period1 %right_out% period2 # получить даты из period2 которые не входят в period1

У пакета timeperiodsR ёсць афіцыйны, рускамоўны плэйліст на YouTube.

Заключэнне

Мы падрабязна разгледзелі класы аб'ектаў якія прызначаны ў мове R для працы з датамі. Таксама зараз вы ўмееце праводзіць над датамі арыфметычныя аперацыі, і хутка атрымліваць любыя часавыя перыяды з дапамогай пакета. timeperiodsR.

Калі вам цікавая мова R запрашаю вас падпісацца на мой тэлеграм канал R4marketing, у якім я на штодзённай аснове дзялюся карыснымі матэрыяламі аб прымяненні мовы R у вырашэнні сваіх паўсядзённых задач.

Крыніца: habr.com

Дадаць каментар