При построении графиков временных рядов иногда бывает нужно объединить два ряда в один график. Чаще всего это бывает необходимо в двух случаях:
- каждый из рядов имеет разную размерность
- размерность одна, но ряды отличаются на порядок или несколько порядков по величине.
К примеру, мы хотим построить график индекса S&P 500 и цены нефти марки Brent для того, чтобы посмотреть, есть ли визуальная зависимость между двумя рядами. Для начала получим исходные данные из базы данных Федерального резервного банка Сент-Луиса - FRED c помощью отличной библиотеки для получения бесплатных финансово-экономических данных quantmod.
require(quantmod)
Sys.setenv(TZ = "GMT") # необходимо установить часовой пояс на GMT, чтобы без скачивание из FRED работало без ошибок
spx <- getSymbols("SP500", src = "FRED", auto.assign = FALSE) #S&P 500 Stock Price Index (SP500)
brent <- getSymbols("DCOILBRENTEU", src = "FRED", auto.assign = FALSE) #Crude Oil Prices: Brent - Europe
API базы данных FRED работает таким образом, что он возвращает все историю в каждом вызове. Задать временной интервал за который необходимы данные, в действующей реализации невозможно. Скорее всего, они добавят это в будущем, чтобы снизить нагрузки на свои сервера. С нашей точки зрения, это приводит к тому, что данные по индексу S&P 500 доступны с 1957 года. plot(spx)
plot(brent)
А данные по ценам на нефть - с 1987 года. Мы же хотим, к примеру, только цифры за последние 5 лет.
brent <- brent["2007::"] # возьмем данные по нефти только с 2007 года
data <- merge(spx, brent, join = "right") #объединим индикаторы в один объект xts
names(data) <- c("spx", "brent") # присвоим нашим имена
Параметр join в функции merge.xts определяет каким образом, осуществляется “слияние” рядов. В нашем случае мы определили слияние по правой переменной (right). Это означает, что в новый объект должны войти все показатели правой переменной и только те значения левой переменной, которые совпадают с
правой.
В R очень легко комбинировать несколько графиков в один визуальный элемент. Параметр mfrow позволяет задавать матрицу из n-строк и m-столбцов, который заполняются построчно. par(mfrow = c(2, 1)) # строим графики в 2 строках и 1 столбце
plot(data$spx, main = "S&P 500")
plot(data$brent, main = "Brent")
Графики совмещены точно друг над другом, что позволяет соотносить их между собой. Это стандартная рекомендация от специалистов по R, когда необходимо строить графики временных рядов для сравнения друг с другом. Но что делать, если все таки необходимо объединить два ряда в один график и нарисовать разные левые и правые оси для оси Y?
Как обычно в R можно один и тот же результат получить с помощью разных инструментов. Наиболее простой вариант следующий. С помощью того же параметра new можно “заставить” R нарисовать на месте уже нарисованного. Так как оба наших ряда полностью совпадают по оси Х (времени), то все будет выглядеть абсолютно нормально. Создадим специальную функцию для этого, чтобы можно было ее использовать в будущем для разных рядов:
Plot2Axis <- function(y1, y2, name1, name2) {
y <- merge(y1, y2)
plot.zoo(na.omit(y[, 1]), type = "l", col = "#3266cc", lwd = 2, main = "",
xlab = "Дата", ylab = "points", oma = c(4, 4, 2, 0.5))
grid() #нарисовать сеточку
par(new = TRUE) # параметр, который позволяет рисовать новый график на текущем графике
plot.zoo(na.omit(y[, 2]), type = "l", col = "#db3a10", lwd = 2, xaxt = "n",
yaxt = "n", xlab = "", ylab = "", oma = c(4, 4, 2, 0.5))
axis(4) #построим ось второго графика слева
legend("topright", col = c("#3266cc", "#db3a10"), lty = 1, lwd = 3, bty = "n",
legend = c(name1, name2), text.col = c("#3266cc", "#db3a10"))
}
# теперь можно использовать функцию,
# задав предварительно несколько
# глобальных параметров, чтобы график
# выглядел более привлекательно
par(bty = "l") # глобальный параметр - граница вокруг графика слева и снизу
par(las = 1) # глобальный параметр - текст пишется параллельно оси X
par(mar = c(2, 4, 1, 3)) # глобальный параметр - границы между область графика и остальной частью
Plot2Axis(data$spx, data$brent, "S&P 500", "Brent")
Примечание: данный пост создавался с помощью пакета knitr, который не всегда дружит с кириллицей в текущей реализации. Поэтому я не стал использовать надписи на кириллице в графиках. В самом R все отображается правильно.
-->