Search code examples
rggplot2quantmod

Multiple time series plots for several stocks in R returns an error


I have a time series data with multiple stocks. I would like to plot them in one plot in R.

I tried an existing answer in this website but I got an error. Here is my code:

library(quantmod)
library(TSclust)
library(ggplot2)
# download financial data

symbols = c('ASX', 'AZN', 'BP', 'AAPL')
start = as.Date("2014-01-01")
until = as.Date("2014-12-31")

stocks = lapply(symbols, function(symbol) {
    Close = getSymbols(symbol,src='yahoo', from = start, to = until, auto.assign = FALSE)[, 6]
   names(adjust) = symbol
    adjust
  })

I tried the following from an exiting answer (from here)

qplot(symbols, value, data = as.data.frame(stocks), geom = "line", group = variable) +
  facet_grid(variable ~ ., scale = "free_y")

I got the following error:

Error: At least one layer must contain all faceting variables: variable.

  • Plot is missing variable
  • Layer 1 is missing variable

I would like to have similar to the following plot:

here


Solution

  • The error messages in the original code are caused by the fact that there is no column called variable in the data that is passed to qplot(). Additionally, in order to produce the desired chart, we need to extract the dates from the xts objects generated by quantmod so we can use them as the x axis variable in the chart.

    With some adjustments to place the appropriate variables from the stock data into the qplot() specification we can produce the required chart.

    We modify the code to read the list of stocks as follows:

    • Convert the xts objects to objects of type data.frame
    • Rename columns to eliminate ticker symbols so we can rbind() into a single data frame in a subsequent step
    • Extract the rownames() into a data frame column

    Having made these changes, the stocks object contains a list of data frames, one per stock ticker.

    symbols = c('ASX', 'AZN', 'BP', 'AAPL')
    start = as.Date("2014-01-01")
    until = as.Date("2014-12-31")
    
    stocks = lapply(symbols, function(symbol) {
         aStock = as.data.frame(getSymbols(symbol,src='yahoo', from = start, to = until, 
                             auto.assign = FALSE))
         colnames(aStock) <- c("Open","High","Low","Close","Volume","Adjusted")
         aStock$Symbol <- symbol
         aStock$Date <- rownames(aStock)
         aStock
    })
    

    Next, we use do.call() with rbind() to combine the data into a single data frame that we'll use with qplot()`.

    stocksDf <- do.call(rbind,stocks)
    

    Finally, we use qplot() with Date and Close as the x and y variables, and facet_grid() with Symbol to generate the facets.

    qplot(Date, Close, data = stocksDf, geom = "line", group = Symbol) +
         facet_grid(Symbol ~ ., scale = "free_y")
    

    ...and the initial output:

    enter image description here

    Having generated the chart, we'll make some adjustments to clean up the x axis labels. On the default chart they are unintelligible because there are 251 different character values, and we need to rescale the axis to print fewer labels.

    First, we convert the character-based dates with as.Date(). Second, we use the ggeasy package to adjust the content on the x axis.

    stocks = lapply(symbols, function(symbol) {
         aStock = as.data.frame(getSymbols(symbol,src='yahoo', from = start, to = until, 
                             auto.assign = FALSE))
         colnames(aStock) <- c("Open","High","Low","Close","Volume","Adjusted")
         aStock$Symbol <- symbol
         aStock$Date <- as.Date(rownames(aStock),"%Y-%m-%d")
         aStock
    })
    stocksDf <- do.call(rbind,stocks)
    library(ggeasy)
    qplot(Date, Close, data = stocksDf, geom = "line", group = Symbol) +
         facet_grid(Symbol ~ ., scale = "free_y") +
         scale_x_date(date_breaks = "14 days") +
         easy_rotate_x_labels(angle = 45, side = "right")
    

    ...and the revised output:

    enter image description here

    NOTE: to chart the Adjusted Closing price, simply change the y variable in the qplot() function to Adjusted.