Работа с дати в R (основни възможности, както и пакетите lubridate и timeperiodsR)

Получаването на текущата дата на какъвто и да е програмен език е еквивалентно на "Hello world!". R не е изключение.

В тази статия ще разгледаме как се работи с дати в основния синтаксис на R, а също така ще обсъдим няколко полезни пакета, разширяващи възможностите му при работа с дати:

  • lubridate — пакет, позволяващ извършване на аритметични операции между дати;
  • timeperiodsR — пакет за работа с времеви интервали и техните компоненти.

Работа с дати в R (основни възможности, както и пакетите lubridate и timeperiodsR)

Съдържание

Ако се интересувате от анализ на данни, и по-специално от R, вероятно ще ви интересуват моите telegram и 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")

format приема в струнен вид оператори, обозначаващи какъвто и да е времеви интервал и неговия формат; най-често използваните стойности са представени в таблицата по-долу:

Формат
Описание

%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), началото на седмицата е в понеделник

Съответно, "26 септември 2019" е – пълното наименование на месеца, ден и година. Описването на този формат на датата с оператори може да стане така:"%B %d, %Y".

Където:

  • %B — Пълното наименование на месеца
  • %d — Номер на деня в месеца
  • %Y — Четиризначно обозначение на година

При описването на формата на датата е важно да включите всички допълнителни символи от вашата низ, например тирета, запетаи, точки, пространства и така нататък. В моят пример, "26 септември 2019", след датата стои запетая, и в описанието на формата също трябва да поставите запетая:"%B %d, %Y".

Има ситуации, когато получавате дата, която не само не съответства на стандартните формати (ГГГГ-ММ-ДД или ГГГГ/ММ/ДД), а също и на език, който се различава от зададения по подразбиране в вашата операционна система. Например, вие сте заредили данни, където датата е посочена по следния начин: "15 декември 2019 г.". Преди конвертиране на този низ в дата, е необходимо да промените локализацията.

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

Извличане на компоненти от дата в основния R

В базовия R не съществуват много функции, позволяващи извличане на част от датата от обекта на клас Date.

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

Освен основния клас на обектите Date в базовия R съществуват още 2 типа данни, които съхраняват времеви печат: POSIXlt, POSIXct. Основното отличие на тези класове е, че освен датата, те съхраняват и времето. Date Sys.time()

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

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

# "POSIXct" "POSIXt"

Функция върща текущата дата и време в формат . Този формат по смисъл е подобен на POSIXctUNIXTIME , и съхранява в себе си броя на секундите от началото на ерата на 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 — Число, низ или обект на клас Date, който трябва да бъде преобразуван;
  • tz — Часова зона, по подразбиране "GMT";
  • format — Описание на формата на датата, в който са представени данните, предавани на аргумент x;
  • origin — Използва се само при конвертиране на число в POSIX, в този аргумент трябва да предадете обект на дата и време, от който започва отсчетът на секундите. Обикновено се използва за преобразуване от UNIXTIME.

Ако вашите данни за дата и време са представени в , и съхранява в себе си броя на секундите от началото на ерата на UNIX, то за да ги конвертирате в разбираема, четима дата, използвайте следния пример:

# Конвертируем 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 — закръгление към най-близкия момент

Всяка от тези функции има аргумент unit, който ви позволява да посочите единица за закръгление: second, minute, hour, day, week, month, 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 клас tpr, от който лесно можете да получите следните компоненти:

  • датата на начало на периода, в нашия пример това е предишният месец
  • датата на край на периода
  • броя на дните, които влизат в периода
  • последователност от дати, които влизат в периода

Също така можете да получите всеки от компонентите по различни начини:

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

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

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

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

Също така можете да получите който и да е от компонентите, използвайки аргумента part, който присъства във всяка от функциите на пакета. Възможни стойности: 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)

 Времеви период: от 9 септември 2019 г., понеделник до 29 септември 2019 г., неделя

6 октомври е неделя:
Работа с дати в R (основни възможности, както и пакетите lubridate и timeperiodsR)

Нуждаем се от период, който относно 6 октомври ще вземе 3 предишни седмици. Не включително седмицата, в която е самият 6 октомври. Следователно, това е периодът от 9 до 29 септември.

Работа с дати в R (основни възможности, както и пакетите lubridate и timeperiodsR)

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

 Времеви период: от 1 май 2019 г., сряда до 31 май 2019 г., петък

В този пример ни интересува месецът, който беше преди 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, каня ви да се абонирате за моя Telegram канал R4marketing, в който ежедневно споделям полезни материали за приложението на езика R в решаването на ежедневните си задачи.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster