Ответ 1
Вот что я сделал:
x$Date = as.Date(x$Date,format="%m/%d/%Y")
x = xts(x=x$Used, order.by=x$Date)
# To get the start date (305)
# > as.POSIXlt(x = "2011-11-01", origin="2011-11-01")$yday
## [1] 304
# Add one since that starts at "0"
x.ts = ts(x, freq=365, start=c(2011, 305))
plot(forecast(ets(x.ts), 10))
Результат:
Что мы можем извлечь из этого:
- Многие из ваших шагов могут быть объединены, уменьшая количество промежуточных объектов, которые вы создаете.
- Выход по-прежнему не такой красивый, как @joran, но он все еще легко читается.
2011.85
означает "число дней365*.85
" (день 310 в году). - Вычисление дня в году можно сделать, используя
as.POSIXlt(x = "2011-11-01", origin="2011-11-01")$yday
, и выяснить дату с номера дня можно, используя что-то вродеas.Date(310, origin="2011-01-01")
Update
Вы можете сбросить еще более промежуточные шаги, так как нет оснований для первого преобразования ваших данных в xts.
x = ts(x$Used, start=c(2011, as.POSIXlt("2011-11-01")$yday+1), frequency=365)
# NOTE: We have only selected the "Used" variable
# since ts will take care of dates
plot(forecast(ets(x), 10))
Это дает тот же результат, что и изображение выше.
Обновление 2
Основываясь на решении, предоставленном @joran, вы можете попробовать:
# 'start' calculation = `as.Date("2011-11-01")-as.Date("2011-01-01")+1`
# No need to convert anything to dates at this point using xts
x = ts(x$Used, start=c(2011, 305), frequency=365)
# Directly plot your forecast without your axes
plot(forecast(ets(x), 10), axes = FALSE)
# Generate labels for your x-axis
a = seq(as.Date("2011-11-01"), by="weeks", length=11)
# Plot your axes.
# `at` is an approximation--there probably a better way to do this,
# but the logic is approximately 365.25 days in a year, and an origin
# date in R of `January 1, 1970`
axis(1, at = as.numeric(a)/365.25+1970, labels = a, cex.axis=0.6)
axis(2, cex.axis=0.6)
Что даст:
Часть проблемы в исходном коде состоит в том, что после преобразования данных в объект xts
и преобразования в объект ts
вы теряете даты в своих точках forecast
.
Сравните первый столбец (Point
) вашего вывода x.fore
со следующим:
> forecast(ets(x), 10)
Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
2012.000 741.6437 681.7991 801.4884 650.1192 833.1682
2012.003 741.6437 676.1250 807.1624 641.4415 841.8459
2012.005 741.6437 670.9047 812.3828 633.4577 849.8298
2012.008 741.6437 666.0439 817.2435 626.0238 857.2637
2012.011 741.6437 661.4774 821.8101 619.0398 864.2476
2012.014 741.6437 657.1573 826.1302 612.4328 870.8547
2012.016 741.6437 653.0476 830.2399 606.1476 877.1399
2012.019 741.6437 649.1202 834.1672 600.1413 883.1462
2012.022 741.6437 645.3530 837.9345 594.3797 888.9078
2012.025 741.6437 641.7276 841.5599 588.8352 894.4523
Надеюсь, это поможет вам понять проблему с вашим оригинальным подходом и улучшить вашу способность работать с временными рядами в R.
Обновление 3
Финальное и более точное решение - потому что я избегаю другой работы, которую я должен делать прямо сейчас...
Используйте пакет lubridate
для лучшей обработки даты:
require(lubridate)
y = ts(x$Used, start=c(2011, yday("2011-11-01")), frequency=365)
plot(forecast(ets(y), 10), xaxt="n")
a = seq(as.Date("2011-11-01"), by="weeks", length=11)
axis(1, at = decimal_date(a), labels = format(a, "%Y %b %d"), cex.axis=0.6)
abline(v = decimal_date(a), col='grey', lwd=0.5)
Результат:
Обратите внимание на альтернативный метод определения даты начала для вашего объекта ts
.