Получаването на текущата дата на какъвто и да е програмен език е еквивалентно на "Hello world!". R не е изключение.
В тази статия ще разгледаме как се работи с дати в основния синтаксис на R, а също така ще обсъдим няколко полезни пакета, разширяващи възможностите му при работа с дати:
lubridate— пакет, позволяващ извършване на аритметични операции между дати;timeperiodsR— пакет за работа с времеви интервали и техните компоненти.

Съдържание
Ако се интересувате от анализ на данни, и по-специално от R, вероятно ще ви интересуват моите и канали. По-голямата част от съдържанието е посветено на R.
1.1.
1.2.
2.1.
2.2.
2.3.
3.1.
3.2.
Работа с дати в основния синтаксис на 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 октомври е неделя:

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

# получить месяц отстающий на 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 има официален, българоезичен .
Заключение
Подробно разгледахме класовете обекти, предназначени в езика R за работа с дати. Сега можете също така да извършвате аритметични операции с дати и бързо да получавате всякакви времеви периоди с помощта на пакета timeperiodsR.
Ако се интересувате от езика R, каня ви да се абонирате за моя Telegram канал , в който ежедневно споделям полезни материали за приложението на езика R в решаването на ежедневните си задачи.
Източник: habr.com
