Узнаем дату, запросив её у системы:
Sys.Date()
## [1] "2019-05-31"
Если попробуем обойтись без модуля Sys
, получим сразу и дату, и время, и день недели:
date()
## [1] "Fri May 31 18:24:39 2019"
Те элементы, которые мы получили, имеют разные типы: первый результат имеет особый тип Date
, который можно преобразовать в число (число секунд, например, отсюда double
в typeof()
), а второй является обычной строкой.
class(Sys.Date())
## [1] "Date"
typeof(Sys.Date())
## [1] "double"
class(date())
## [1] "character"
Тот же строковый тип мы получим, если посмотрим на обычную дату, сохраненную как текст:
class("2019-04-25")
## [1] "character"
Если мы хотим работать с датами и временем, такой формат данных нам неудобен: мы не сможем вычесть из одной строки другую и понять, сколько времени прошло с одного момента времени до другого. Можно, конечно, написать свою функцию, которая будет разделять строку с датой-временем на части и приводить все к числовому виду, но это неудобно и нерационально. В R есть специальная функция as.Date()
, которая приводит строку к типу Date
:
date1 <- as.Date("2019-04-25")
date1
## [1] "2019-04-25"
str(date1)
## Date[1:1], format: "2019-04-25"
По умолчанию считается, что на первом месте указан год, на втором — месяц, на третьем — день. Если порядок будет иным, функция сломается:
as.Date("27-05-2019")
## [1] "0027-05-20"
Ошибки нет, но результат странный. Чтобы этого избежать, формат можно задать самостоятельно: написать текстовый шаблон, который бы описывал нужный формат даты. Сообщим R, что на первом месте год, на втором — месяц, на третьем — день, плюс, напомним, что разделителем является дефис:
date2 <- as.Date("27-05-2019", format = "%d-%m-%Y")
date2
## [1] "2019-05-27"
Узнать, какие ещё существуют обозначения и чему они соответствуют, можно здесь.
Задание: преобразовать в тип Date
следующие даты:
Решения:
as.Date("05-13-19", format = "%m-%d-%y")
## [1] "2019-05-13"
as.Date("апр 25 2019", format = "%B %d %Y")
## [1] "2019-04-25"
as.Date("май-25-2019", format = "%b-%d-%Y")
## [1] "2019-05-25"
as.Date("четверг фев 21 2019", format = "%A %b %d %Y")
## [1] "2019-02-21"
Также с датами можно выполнять вычисления. Посчитаем разницу между date2
и date1
и наоборот:
date2 - date1
## Time difference of 32 days
date1 - date2
## Time difference of -32 days
По умолчанию разница измеряется в днях, но это можно поправить:
difftime(date1, date2, units = "weeks") # в неделях
## Time difference of -4.571429 weeks
difftime(date1, date2, units = "secs") # в секундах
## Time difference of -2764800 secs
Полный список опций такой:
units <- c("auto", "secs", "mins", "hours", "days", "weeks")
Удобно то, что если у нас есть вектор с датами и нам необходимо посчитать разницу между всеми датами, следующими друг за другом, для этого не понадобится создавать пары последовательных дат, R и так поймёт, что нужно.
three.dates <- as.Date(c("2010-07-22", "2011-04-20", "2012-10-06"))
diff(three.dates) # для трех, в днях
## Time differences in days
## [1] 272 535
Последовательности из дат также легко создавать автоматически — достаточно зафиксировать стартовую точку, сообщить длину нужной последовательности и единицы измерения (секунд/минут/дней/недель и так далее):
days10 <- seq(date1, length = 10, by = "day")
days10 # 10 элементов, шаг 1 день (итого 10 дней)
## [1] "2019-04-25" "2019-04-26" "2019-04-27" "2019-04-28" "2019-04-29"
## [6] "2019-04-30" "2019-05-01" "2019-05-02" "2019-05-03" "2019-05-04"
weeks5 <- seq(date1, length = 5, by = "week")
weeks5 # 5 элементов, шаг 1 неделя
## [1] "2019-04-25" "2019-05-02" "2019-05-09" "2019-05-16" "2019-05-23"
days3 <- seq(date1, length = 5, by = "3 day")
days3 # 5 элементов, шаг 3 дня
## [1] "2019-04-25" "2019-04-28" "2019-05-01" "2019-05-04" "2019-05-07"
Если нужно двитаться в обратную сторону, можно поставить минус перед единицей измерения:
seq(date1, length = 5, by = "-3 day")
## [1] "2019-04-25" "2019-04-22" "2019-04-19" "2019-04-16" "2019-04-13"
seq(date1, length = 5, by = "-1 week")
## [1] "2019-04-25" "2019-04-18" "2019-04-11" "2019-04-04" "2019-03-28"
На этом пока всё.