Анализ данных, содержащих даты и время, может сопровождаться
приличной головной болью. Причин этому может
быть несколько:
- разные годы начинаются в разные дни недели;
- високосные годы имеют дополнительный день в феврале;
- американцы и европейцы по разному представляют даты (например, 8/9/2011 будет 9-м августа 2011 г. для первых и 8-м сентября 2011 г. для вторых);
- в некоторые годы добавляется т.н. "секунда координации";
- страны различаются по временным поясам и в ряде случаев применяют переход на "зимнее" и "летнее" время.
К счастью, система дат и времени в R такова, что многие из указанных проблем относительно легко преодолеваются. С форматом представления дат и времени в R можно ознакомиться, выполнив команду Sys.time()
[1] "2011-09-06 00:38:04 EEST"
Как видим, формат строго иерархичен: сначала идет наболее крупная временная единица - год, потом месяц и день, разделенные дефисом, а затем пробел, час, минуты, секунды и, после еще одного пробела, аббревиатура временной шкалы.
Отдельные элементы из этого результата можно извлечь при помощи функции substr() (от substring - часть строки), указав позиции первого и последнего элементов извлекаемой строки:
substr(as.character(Sys.time()), 1, 10)
[1] "2011-09-06"
или
substr(as.character(Sys.time()), 12, 19)
[1] "00:38:04"
Функция date() позволяет
выяснить текущую дату:
[1] "Tue Sep 06 01:02:24 2011"
Если выполнить команду
unclass(Sys.time())
[1] 1315258719
то получим время, выраженное в секундах, прошедших с 1 января 1970 г. Это т.н. Unix-время (по названию операционной системы). Второе название этого формата - POSIX. В R имеется два POSIX-класса. Класс POSIXct служит для педставления времени в виде секунд, истекших с 1 января 1970 г. Такой "машинный" формат удобен для включения в таблицы данных. Для человека все же более удобным является представление времени при помощи класса POSIXlt. Объекты этого класса представляют собой списки, включающие такие элементы, как секунды, минуты, часы, дни, месяцы, и годы.
Мы можем конвертировать системное время в объект POSIXlt класса следующим образом:
date <- as.POSIXlt(Sys.time())
Из списка date далее легко можно извлечь такие содержащиеся в нем элементы, как sec (секунды), min (минуты), hour (часы), mday (день месяца), mon (месяц), year (год), wday (день недели, начиная с воскресенья = 0), yday (день года, начиная с 1 января = 0), и isdst ("is daylight savings time in operation?" - логическая переменная, обозначающая, используется ли режим перехода на "зимнее" и "летнее" время; 1 если TRUE и 0 если FALSE), например:
Используйте функцию unclass() в сочетании с unlist() для просмотра всего содержимого списка date:
Вычисления с датами и временем
В R можно выполнять следующие типы операций с датами и временем:
Еще проще разницу между двумя датами можно найти при помощи готовой функции difftime() (от difference - разница, и time - время):
Чтобы извлечь непосредственно количество дней из результата выполнения предыдущей команды используйте функцию as.numeric():
Обратите внимание: в R отсуствует возможность для сложения двух дат.
Функция strptime()
Функция strptime() (от strip - раздевать, оголять, и time - время) позволяет извлекать даты и время из текстовых выражений класса POSIXlt или POSIXct (см. выше). При этом важно верно указать формат (при помощи аргумента format), в котором приведены временные величины. Приняты следующие условные обозначения для формата дат и времени (приведены наиболее часто используемые; детали доступны по команде ?strptime):
Вот еще один пример, в котором год приведен без указания века, а месяцы приведены в виде их сокращенных названий:
example2 <- c("1jan79", "2jan99", "31jan04", "30aug05")
strptime(other.dates, "%d%b%y")
[1] "1979-01-01" "1999-01-02" "2004-01-31" "2005-08-30"
--
Основным источником для написания данной статьи послужил раздел "Dates and Times in R" из книги Майкла Кроули (Michael Crawley) "The R Book".
date$wday
[1] 2
[1] 2
date$yday
[1] 248
[1] 248
Используйте функцию unclass() в сочетании с unlist() для просмотра всего содержимого списка date:
unlist(unclass(date))
sec min hour mday mon
29.97798 26.00000 12.00000 6.00000 8.00000
year wday yday isdst
111.00000 2.00000 248.00000 1.00000
Вычисления с датами и временем
В R можно выполнять следующие типы операций с датами и временем:
- число + время;
- время - число;
- время1 - время2
- время1 "логический оператор" время2 (в качестве логического оператора могут использоваться ==, !=, <=, <, > или >=).
t1 <- as.POSIXlt("2011-09-15")
t2 <- as.POSIXlt("2000-09-15")
t1 - t2
Time difference of 4017 days
Разницу во времени, выраженную в часах, можно рассчитать так:
t3<-as.POSIXlt("2010-09-22 08:30:30")
t4<-as.POSIXlt("2010-09-22 22:25:30")
t4-t3
Time difference of 13.91667 hours
t4<-as.POSIXlt("2010-09-22 22:25:30")
t4-t3
Time difference of 13.91667 hours
difftime("2011-09-22", "2010-06-22")
Time difference of 457 days
as.numeric(difftime("2011-09-22", "2010-06-22"))
[1] 457
Функция strptime() (от strip - раздевать, оголять, и time - время) позволяет извлекать даты и время из текстовых выражений класса POSIXlt или POSIXct (см. выше). При этом важно верно указать формат (при помощи аргумента format), в котором приведены временные величины. Приняты следующие условные обозначения для формата дат и времени (приведены наиболее часто используемые; детали доступны по команде ?strptime):
%a сокращенное название для недели (англ. яз.)
%A полное название для недели (англ. яз.)
%b сокращенное название месяца (англ. яз.)
%B полное название месяца (англ. яз.)
%d день месяца (01–31)
%H часы от 00 до 23
%I часы от 01 до 12
%j порядковый номер дня года (001–366)
%m порядковый номер месяца (01–12)
%M минуты (00–59)
%S секунды (00–61, с возможностью добавить "високосную секунду")
%U неделя года (00–53), используя первое вокресенье как первый день первой недели
%w порядковый номер дня недели (0–6, воскресенье - 0)
%W неделя года (00–53), используя первый понедельник как первый день первой недели
%A полное название для недели (англ. яз.)
%b сокращенное название месяца (англ. яз.)
%B полное название месяца (англ. яз.)
%d день месяца (01–31)
%H часы от 00 до 23
%I часы от 01 до 12
%j порядковый номер дня года (001–366)
%m порядковый номер месяца (01–12)
%M минуты (00–59)
%S секунды (00–61, с возможностью добавить "високосную секунду")
%U неделя года (00–53), используя первое вокресенье как первый день первой недели
%w порядковый номер дня недели (0–6, воскресенье - 0)
%W неделя года (00–53), используя первый понедельник как первый день первой недели
%Y год с указанием века
%y год без указания века
%y год без указания века
Рассмотрим пример. Предположим, у нас имеется текстовый вектор, в котором хрянятся даты в формате программы Microsoft Excel:
dates.excel <- c("25/02/2008", "24/04/2009",
"14/06/2009", "25/07/2010", "04/03/2011")
Требуется преобразовать эти текстовые выражения в даты формата R. Формат имеющихся Excel-дат таков, что сначала идет день месяца, затем порядковый номер самого месяца и, наконец, год с указанием века. Используя приведенные выше обозначения, принятые в R, этот формат можно представить в виде %d/%m/%Y. Тогда команда для преобразования Excel-дат в R-даты будет выглядеть следующим образом:
strptime(dates.excel, format = "%d/%m/%Y")
[1] "2008-02-25" "2009-04-24" "2009-06-14"
[2] "2010-07-25" "2011-03-04"
[2] "2010-07-25" "2011-03-04"
Вот еще один пример, в котором год приведен без указания века, а месяцы приведены в виде их сокращенных названий:
example2 <- c("1jan79", "2jan99", "31jan04", "30aug05")
strptime(other.dates, "%d%b%y")
[1] "1979-01-01" "1999-01-02" "2004-01-31" "2005-08-30"
--
Основным источником для написания данной статьи послужил раздел "Dates and Times in R" из книги Майкла Кроули (Michael Crawley) "The R Book".
Как вернуть время?
# Как фрагмент текста
substr(as.character(t), 12, 16)
# Или как элементы списка
t$hour
t$min
Отправить комментарий