问题
I have some timeseries data for 2000-Q1 to 2010-Q4. I have used the data from 2000-Q1 to 2008-Q2 to forecast the next 10 quarters using HoltWinters
CPI.HI.fit <- HoltWinters(CPI.HI.pre, gamma=FALSE)
CPI.HI.cfr <- forecast(CPI.HI.fit, 10)
Here're the data--
CPI.HI.pre
(previous timeseries of thets
class)CPI.HI.pos
(posterior timeseries of thets
class)CPI.HI.cfr
(crisis forecast of theforecast
class)
> CPI.HI.pre
# Qtr1 Qtr2 Qtr3 Qtr4
# 2000 83.12262 83.72945 84.10338 84.58881
# 2001 85.03111 85.92120 85.86388 85.74424
# 2002 86.01310 86.89452 87.05565 87.31702
# 2003 87.93231 88.23959 88.43708 88.56572
# 2004 89.02891 90.05139 90.17285 90.68677
# 2005 90.82155 91.74464 92.18774 92.57043
# 2006 92.91782 94.15888 94.58178 94.13807
# 2007 94.58282 95.99794 96.12194 97.08308
# 2008 97.72470 99.54615
> CPI.HI.pos
# Qtr1 Qtr2 Qtr3 Qtr4
# 2008 100.39960 99.11151
# 2009 98.79588 99.36900 99.75832 99.90321
# 2010 100.17990 100.96250 100.99250 101.40690
> CPI.HI.cfr
# Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
# 2008 Q3 99.86646 99.26724 100.4657 98.95002 100.7829
# 2008 Q4 100.69200 99.93567 101.4483 99.53529 101.8487
# 2009 Q1 101.51754 100.57777 102.4573 100.08028 102.9548
# 2009 Q2 102.34308 101.19808 103.4881 100.59195 104.0942
# 2009 Q3 103.16862 101.79962 104.5376 101.07492 105.2623
# 2009 Q4 103.99416 102.38447 105.6038 101.53236 106.4560
# 2010 Q1 104.81970 102.95412 106.6853 101.96654 107.6729
# 2010 Q2 105.64524 103.50968 107.7808 102.37918 108.9113
# 2010 Q3 106.47077 104.05204 108.8895 102.77163 110.1699
# 2010 Q4 107.29631 104.58191 110.0107 103.14499 111.4476
I am able to get the previous data and forecast in one plot with
> autoplot(CPI.HI.cfr)
and also the actual data for the forecast period in a separate plot with
> autoplot(CPI.HI.pos)
I want both of them together on the same plot.
I understand it can be best done with ggplot()
but after trying several ways
such as
ggplot(aes(x=x, y=y), data=CPI.HI.pre) +
geom_line(CPI.HI.pos)
things started looked confusing to me !
回答1:
So I found your question not very convenient to reproduce and next time you might consider posting the snippets of your data using dput()
. The reason that I think this is because I had to wrange with copy-pasted data in the following way to get something resembling your input:
zz <- " Qtr1 Qtr2 Qtr3 Qtr4
2000 83.12262 83.72945 84.10338 84.58881
2001 85.03111 85.92120 85.86388 85.74424
2002 86.01310 86.89452 87.05565 87.31702
2003 87.93231 88.23959 88.43708 88.56572
2004 89.02891 90.05139 90.17285 90.68677
2005 90.82155 91.74464 92.18774 92.57043
2006 92.91782 94.15888 94.58178 94.13807
2007 94.58282 95.99794 96.12194 97.08308
2008 97.72470 99.54615 NA NA"
yy <- " Qtr1 Qtr2 Qtr3 Qtr4
2008 NA NA 100.39960 99.11151
2009 98.79588 99.36900 99.75832 99.90321
2010 100.17990 100.96250 100.99250 101.40690"
qq <- "Year Qtr PointForecast Lo80 Hi80 Lo95 Hi95
2008 Q3 99.86646 99.26724 100.4657 98.95002 100.7829
2008 Q4 100.69200 99.93567 101.4483 99.53529 101.8487
2009 Q1 101.51754 100.57777 102.4573 100.08028 102.9548
2009 Q2 102.34308 101.19808 103.4881 100.59195 104.0942
2009 Q3 103.16862 101.79962 104.5376 101.07492 105.2623
2009 Q4 103.99416 102.38447 105.6038 101.53236 106.4560
2010 Q1 104.81970 102.95412 106.6853 101.96654 107.6729
2010 Q2 105.64524 103.50968 107.7808 102.37918 108.9113
2010 Q3 106.47077 104.05204 108.8895 102.77163 110.1699
2010 Q4 107.29631 104.58191 110.0107 103.14499 111.4476"
CPI.HI.pre <- read.table(text = zz, header = T)
CPI.HI.pre$year <- rownames(CPI.HI.pre)
CPI.HI.pos <- read.table(text = yy, header = T)
CPI.HI.pos$year <- rownames(CPI.HI.pos)
CPI.HI.cfr <- read.table(text = qq, header = T)
I've copied the rownames into an actual variable for CPI.HI.pre
and CPI.HI.pos
. Also I added the Year
and Qtr
colnames to CPI.HI.cfr
and filled any gaps with NA
s. Next, I converted the data from a long format to a wide format:
df1 <- reshape2::melt(CPI.HI.pre, id.vars = "year")
df2 <- reshape2::melt(CPI.HI.pos, id.vars = "year")
# data of origin saved as an extra column
df <- rbind(cbind(df1, data = "CPI.HI.pre"),
cbind(df2, data = "CPI.HI.pos"))
df <- df[!is.na(df$value),]
# CPI.HI.cfr is already in long format, but wanted to have a shorter variable
fc <- CPI.HI.cfr
Then I converted the year quarter pairs to some numerical value that can be interpreted easily by ggplot. I'm sure someone has better ideas to do date format conversion for example with the lubridate package, but I'm not well-versed in this.
df$x <- as.numeric(df$year) + (as.numeric(factor(df$variable), levels = paste0("Qrt", 1:4)))/4
fc$x <- as.numeric(fc$Year) + (as.numeric(factor(fc$Qtr), levels = paste0("Q", 1:4)))/4
Finally we can plot the data. We're using two transparant geom_ribbons for the 80% and 95% confidence intervals and two lines for the forecasted points and for the actual points.
ggplot(df) +
geom_ribbon(data = fc, aes(x, ymin = Lo95, ymax = Hi95), fill = "blue", alpha = 0.25) +
geom_ribbon(data = fc, aes(x, ymin = Lo80, ymax = Hi80), fill = "blue", alpha = 0.25) +
geom_line(data = fc, aes(x, PointForecast), colour = "blue") +
geom_line(aes(x, value))
Which looked like this:
来源:https://stackoverflow.com/questions/56180717/r-how-to-show-forecast-and-actual-data-in-a-single-plot