I'm trying to create a Holt-Winters forecast from a weekly time series, then plot the original series and forecast using dygraphs. I have 144 weeks of friday week-ending data. For my purpose, I'm ignoring that some years have 53 weeks. The structure of the data can be simulated by:
## create data similar to what I have
week_date <- seq.Date(from = as.Date("2012/05/11"),
by = "week",
length.out = 144)
set.seed(1)
var1 <- diffinv(rnorm(143))
df <- data.frame(cbind(week_date, var1))
## convert to ts object then
## create Holt Winters forecast
dfts <- ts(df[,2],freq=52, start=c(2012,19))
hw <- HoltWinters(dfts)
p <- predict(hw, 4)
all <- cbind(dfts, p)
## create plots
dygraph(all, "time series dygraph") %>%
dySeries("var1", label = "Actual") %>%
dySeries(c("p.lwr", "p.fit", "p.upr"), label = "Predicted")
This produces the following error:
Error in as.xts.ts(data) : could not convert index to appropriate type
I tried the solution proposed here, but am getting the same error:
> all <- cbind(dfts = as.xts(dfts), p = as.xts(p))
Error in as.xts.ts(dfts) : could not convert index to appropriate type
There are a few things going on here. The root of the issue is that the data
parameter of dygraph
requires "Time series data (must be an xts object or an object which is convertible to xts)" (see ?dygraph
).
As you've discovered, converting dfts
to an xts object fails:
> library(xts)
> dfts <- as.xts(dfts)
Error in as.xts.ts(dfts) : could not convert index to appropriate type
If you try to create the xts object directly:
> dfts <- xts(dfts)
Error in xts(dfts) : order.by requires an appropriate time-based object
This is because, by default xts
uses index(x)
for the order.by
parameter. From ?xts
:
order.by a corresponding vector of unique times/dates -
must be of a known time-based class
...
Currently acceptable classes include: ‘Date’, ‘POSIXct’, ‘timeDate’,
as well as ‘yearmon’ and ‘yearqtr’ where the index values remain unique.
And if you look at the index on dfts
:
> str(index(dfts))
num [1:148] 2012 2012 2012 2012 2012 ...
> head(index(dfts))
[1] 2012.346 2012.365 2012.385 2012.404 2012.423 2012.442
The index is numeric, while xts
requires some type of date object, so you'll need to convert it.
First, I'd create the all
object by converting each to a zoo
object and then merging:
> library(zoo)
> # You'll need prediction.interval=TRUE to get the bounds:
> p <- predict(hw, 4, prediction.interval=TRUE)
> all <- merge(actual=as.zoo(dfts), predicted=as.zoo(p))
> head(all)
actual fit upr lwr
2012(19) 0.0000000 NA NA NA
2012(20) -0.6264538 NA NA NA
2012(21) -0.4428105 NA NA NA
2012(22) -1.2784391 NA NA NA
2012(23) 0.3168417 NA NA NA
2012(24) 0.6463495 NA NA NA
Then, you can cast it to an xts
object by converting the decimal index to a date. There are a few ways to do this, but the easiest is probably to use the date_decimal
function from the lubridate
package:
> library(lubridate)
> all.xts <- xts(all, date_decimal(index(all)))
Now, tweaking the parameters in the dygraph function:
> dygraph(all.xts, "time series dygraph") %>%
dySeries("actual", label = "Actual") %>%
dySeries(c("lwr", "fit", "upr"), label = "Predicted")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With