рекомендации

воскресенье, 26 апреля 2015 г.

Работа с финансовыми временными рядами в R. Часть 2. Класс Date (base R)


Класс Date используется для представления индекса времени, где отображаются только календарные даты, но не время внутри суток. Внутри объекта класса Date дата представлена в виде количества дней с 1 января 1970 года. Вы можете создать объект класса Date из символьной строки, предствляющей дату, с помощью функции as.Date(). Формат строки по умолчанию “YYYY/m/d” or “YYYY-m-d”, где YYYY - год, m - месяц, d - день. 

Пример:

> my.date = as.Date("1970/1/1")
> my.date
[1] "1970-01-01"
> class(my.date)
[1] "Date"
> as.numeric(my.date)
[1] 0
> myDates = c("2013-12-19", "2003-12-20")
> as.Date(myDates)
[1] "2013-12-19" "2003-12-20"

Если формат даты отличается от заданного по умолчанию, его можно указать явно с помощью аргумента “format”:


> as.Date("1/1/1970", format="%m/%d/%Y")
[1] "1970-01-01"
> as.Date("January 1, 1970", format="%B %d, %Y")
[1] "1970-01-01"
> as.Date("01JAN70", format="%d%b%y")
[1] "1970-01-01"

Обратите внимание, что формат вывода всегда “YYYY-m-d”, независимо от входного формата. Изменить его можно с помощью функции format():

> format(my.date, "%b %d, %Y")
[1] "Jan 01, 1970"

Некоторые форматы дат не обеспечивают достаточно информации, чтобы быть представленными в виде объекта класса Date. Пример:

> as.Date("Jan 1970", format="%b %Y")
[1] NA

В таблице 2 представлены стандартные коды форматов даты:

код
значение
пример
%d
день месяца (десятичное число)
23
%m
месяц (десятичное число)
11
%b
месяц (аббревиатура)
Jan
%B
месяц (полное название)
January
%y
год (две цифры)
90
%Y
год (четыре цифры)
1990

Напомним, что даты хранятся в памяти к целое число дней с 1 января 1970 года, поэтому вы можете создать объект класса Date из целого числа. Один из способов - преобразовать целую переменную в объект Date с использованием функции class():

> my.date = 0
> class(my.date) = "Date"
> my.date
[1] "1970-01-01"
Другой способ - использовать функцию as.Date() с опциональным аргументом “origin”, если дата начала отсчета отличается от  01.01.1970. Например, определим дату, отстоящую на 32500 дней от 01.01.1900:

> as.Date(32500, origin=as.Date("1900-01-01"))
[1] "1988-12-25"

Извлечение информации из объектов класса Date

Рассмотрим объект класса Date:

> my.date
[1] "1970-01-01"

Предположим, я хочу извлечь из него информацию о годовом компоненте даты в виде строки символов. Это можно сделать с помощью функции format().

> myYear = format(my.date, "%Y")
> myYear
[1] "1970"
> class(myYear)
[1] "character"
> as.numeric(myYear)
[1] 1970
> as.numeric(format(my.date, "%Y"))
[1] 1970
Указывая различные коды формата в функции format(), я могу извлекать и другие компоненты, такие как месяц или день. Кроме того, для извлечения специфических компонентов из объектов класса Date могут также использоваться функции weekdays(), months(), quarters() и julian().

> weekdays(my.date)
[1] "Thursday"
> months(my.date)
[1] "January"
> quarters(my.date)
[1] "Q1"
> julian(my.date, origin=as.Date("1900-01-01"))
[1] 25567
attr(,"origin")
[1] "1900-01-01"

Работа с объектами класса Date

Численное представление дат позволяет позволяет производить с ними некоторые простые арифметические операции, например:

> my.date
[1] "1970-01-01"
> my.date + 1
[1] "1970-01-02"
> my.date - 1
[1] "1969-12-31"
> my.date + 31
[1] "1970-02-01"

Также могут выполняться логические операции:

> my.date
[1] "1970-01-01"
> my.date1 = as.Date("1980-01-01")
> my.date1 > my.date
[1] TRUE
При вычитании двух дат создается объект difftime, содержащий количество дней между двумя датами.

> diff.date = my.date1 - my.date
> diff.date
Time difference of 3652 days
> class(diff.date)
[1] "difftime"
> as.numeric(diff.date)
[1] 3652
> my.date + diff.date
[1] "1980-01-01"
Создание последовательностей дат   

Очень часто для конструирования временных рядов требуются последовательности дат. Функция seq() из базового набора R (с функцией-методом seq.Date() для объектов класса Date) позволяет создавать различные типы последовательностей дат. Аргументы функции seq.Date():

> args(seq.Date)
function (from, to, by, length.out = NULL, along.with = NULL,
...)

где “from” - задает дату начала последовательности, “to” - дату окончания, “by” - инкремент, который является символьной строкой и может принимать значения “day”, “week”, “month” или “year”, перед ним может стоять положительное или отрицательное число, также он может оканчиваться символом “s”. Например, создадим двухмесячную последовательность объектов Date, начиная с 01.03.1993, и заканчивая 01.03.2003:

> my.dates = seq(as.Date("1993/3/1"), as.Date("2003/3/1"), "2 months")
> head(my.dates)
[1] "1993-03-01" "1993-05-01" "1993-07-01" "1993-09-01" "1993-11-01"
[6] "1994-01-01"
> tail(my.dates)
[1] "2002-05-01" "2002-07-01" "2002-09-01" "2002-11-01" "2003-01-01"
[6] "2003-03-01"
Или
> my.dates = seq(from=as.Date("1993/3/1"), by="2 months", length.out=61)
Функция seq() также используется для определения даты, отстоящей от текущей даты на заданное количество дней, недель, месяцев или лет. Например, найдем дату, отстоящую от сегодняшнего дня на 5 месяцев:

> Sys.Date()
[1] "2014-01-10"
> seq(from=Sys.Date(), by="5 months", length.out=2)[2]
[1] "2014-06-10"
Хотя это решение правильное, оно не очень интуитивно. Пакет lubridate, который будет описан позже, обеспечивает более простое решение.

Визуализация объектов Date

Для графического отображения распределения данных в объекте класса Date служит функция hist() (с функцией-методом hist.Date()). Например, приведенный ниже код генерирует 500 случайных дат с 01.01.2013 года по 01.01.2014 года и строит гистограмму распределения количества дат в каждом месяце.

> rint = round(runif(500)*365)
> startDate = as.Date("2013-01-01")
> myDates = startDate + rint
> head(myDates)
[1] "2013-10-05" "2013-10-23" "2013-11-20" "2013-05-27" "2013-07-11" "2013-
06-07"
> hist(myDates, breaks="months", freq=TRUE, main="Distribution of Dates by Month", col="slateblue1", xlab="", format="%b %Y", las=2)

Полученная в результате гистограмма показана на рис. 1.  

R01.png

Рисунок 1. Гистограмма объекта Date.

Комментариев нет:

Отправить комментарий