How to change the date format from yearmon to yyyy

2019-07-02 06:07发布

问题:

My ultimate bjective is to plot the monthly S&P 500, Sotheby's, and Industrial Production into one normalized ggplot2, including recession bars.

I collect my data via quantmod and Quandl:

#======= LOAD PACKAGES ====================================
library(tseries)
library(quantmod)
library(Quandl)
library(ggplot2)
library(forecast)
library(urca)

#======= DATA IMPORT ======================================
env1 = new.env()
getSymbols("^GSPC", env = env1, src ="yahoo", from = as.Date("1988-06-01"),to = as.Date("2013-04-01"))
GSPC = env1$GSPC
gspc.df = data.frame(date=time(GSPC), coredata(GSPC))

env2 = new.env()
getSymbols("BID", env = env2, src ="yahoo", from = as.Date("1988-06-01"),to = as.Date("2013-04-01"))
BID = env2$BID
sothebys.df = data.frame(date=time(BID), coredata(BID))

INDPRO <- Quandl("FRED/INDPRO", start_date="1988-06-01",end_date="2013-05-29",type="xts")
indpro.df = data.frame(date=time(INDPRO), coredata(INDPRO))

Afterwards, I transform the daily data to monthly data:

# Transform data to monthly time series
GSPCM <- to.monthly(GSPC)
gspcm.df = data.frame(date=time(GSPCM), coredata(GSPCM))

BIDM <- to.monthly(BID)
sothebysm.df = data.frame(date=time(BIDM), coredata(BIDM))

INDPROM <- to.monthly(INDPRO)
indprom.df = data.frame(date=time(INDPROM), coredata(INDPROM))

Then, I am constructing the data.frame for the plot:

# Build the dataframe with monthly dates and stock prices to be used in graphing
dfm = data.frame(Date = gspcm.df$date, GSPCM = gspcm.df$GSPC.Adjusted, BIDM = sothebysm.df$BID.Adjusted, INDPROM = indprom.df$INDPRO.Close)

Finally, I try to build a ggplot2 with recession bars as described (See Link):

recessions.df = read.table(textConnection(
  "Peak, Trough
  1857-06-01, 1858-12-01
  1860-10-01, 1861-06-01
  1865-04-01, 1867-12-01
  1869-06-01, 1870-12-01
  1873-10-01, 1879-03-01
  1882-03-01, 1885-05-01
  1887-03-01, 1888-04-01
  1890-07-01, 1891-05-01
  1893-01-01, 1894-06-01
  1895-12-01, 1897-06-01
  1899-06-01, 1900-12-01
  1902-09-01, 1904-08-01
  1907-05-01, 1908-06-01
  1910-01-01, 1912-01-01
  1913-01-01, 1914-12-01
  1918-08-01, 1919-03-01
  1920-01-01, 1921-07-01
  1923-05-01, 1924-07-01
  1926-10-01, 1927-11-01
  1929-08-01, 1933-03-01
  1937-05-01, 1938-06-01
  1945-02-01, 1945-10-01
  1948-11-01, 1949-10-01
  1953-07-01, 1954-05-01
  1957-08-01, 1958-04-01
  1960-04-01, 1961-02-01
  1969-12-01, 1970-11-01
  1973-11-01, 1975-03-01
  1980-01-01, 1980-07-01
  1981-07-01, 1982-11-01
  1990-07-01, 1991-03-01
  2001-03-01, 2001-11-01
  2007-12-01, 2009-06-01"), sep=',',
colClasses=c('Date', 'Date'), header=TRUE)
recessions.trim = subset(recessions.df, Peak >= min(gspc.df$date))
g.gspc = ggplot(data = dfm) + geom_line(aes(x = Date, y = GSPCM, colour = "blue")) + geom_line(aes(x = Date, y = BIDM, colour = "red")) + geom_line(aes(x = Date, y = INDPROM, colour = "green")) + theme_bw()
g.gspc = g.gspc + geom_rect(data=recessions.trim, aes(xmin=Peak, xmax=Trough, ymin=-Inf, ymax=+Inf), fill='pink', alpha=0.4)
plot(g.gspc)

Here the following error message is returned:

Don't know how to automatically pick scale for object of type yearmon. Defaulting to continuous. Fehler: Discrete value supplied to continuous scale

I assume it has something to do with the date format in my dataframe and the date format in the recessions.df. Again, your help would be highly appreciated. Hope the code is not too lengthy.

P.S. If there is a way to generate the same chart including recession bars with the ChartSeries Tool from Quantmod, that would be awesome...

回答1:

Your current setup will work if you convert the Date from yearmon to Date before plotting.

dfm = data.frame(Date = as.Date(gspcm.df$date), GSPCM = gspcm.df$GSPC.Adjusted,
    BIDM = sothebysm.df$BID.Adjusted, INDPROM = indprom.df$INDPRO.Close)


回答2:

There is functionality for directly handling yearmon axes in the development version of zoo (update: now released as part of zoo 1.7-10):

library(zoo) # 1.7-10 or higher required
library(ggplot2)
library(scales)

z <- zoo(1:12, Sys.yearmon() + 1:12/12)
autoplot(z) + scale_x_yearmon()

scale_x_yearmon has a format argument which takes the usual percent codes.

UPDATE: scale_x_yearmon has now been released.