## Basic packages
library(knitr)
library(kableExtra)
library(tidyverse)
library(magrittr)
library(tsibble)
library(lubridate)
## Specialized packages
library(forecast)
library(fable)
library(feasts)
library(fabletools)
library(stats)
library(gets)
1. Different Functions for Autoregressive Models
A new index i is used.
tsi <- read_csv("../../data/Fulton.csv") %>%
# mutate(p = exp(LogPrice)) %>%
mutate(t = ymd(Date)) %>%
mutate(p.log = LogPrice) %>%
mutate(i = row_number()) %>%
select(i, t, p.log) %>%
as_tsibble(index = i)
mods <- list()
mods[[1]] <- tsi %>%
{.$p.log} %>%
ar.ols(aic = FALSE, order.max = 1, demean = F, intercept = T)
mods[[2]] <- tsi %>%
{.$p.log} %>%
ar.mle(aic = FALSE, order.max = 1, demean = T, intercept = F)
# There is no way for `ar.mle` to estimate the intercept directly.
mods[[3]] <- tsi %>%
{.$p.log} %>%
arima(order = c(1, 0, 0), include.mean = T, method = "ML")
# There is no way for `arima` to estimate the intercept directly.
mods[[4]] <- tsi %>%
{.$p.log} %>%
gets::arx(mc = T, ar = 1, mxreg = NULL, qstat.options = c(1,1))
mods[[5]] <- tsi %>%
model(fable::ARIMA(p.log ~ 1 + pdq(1, 0, 0)))
mods[[6]] <- tsi %>%
{.$p.log} %>%
arima(order = c(1, 0, 0), include.mean = T, method = "CSS")
tibble(
hwi_mods = 1:6,
intercept = c(
mods[[1]]$x.intercept,
as.double(mods[[2]]$x.mean) * (1 - as.double(mods[[2]]$ar)),
as.double(mods[[3]]$coef[2] * (1 - mods[[3]]$coef[1])),
mods[[4]]$coefficients[1],
as.double(coef(mods[[5]])[2, 3]),
as.double(mods[[6]]$coef[2] * (1 - mods[[6]]$coef[1]))
),
ar1 = c(
mods[[1]]$ar[1],
as.double(mods[[2]]$ar),
as.double(mods[[3]]$coef[1]),
mods[[4]]$coefficients[2],
as.double(coef(mods[[5]])[1, 3]),
as.double(mods[[6]]$coef[1])
)
) %>%
kable_inline()
| hwi_mods |
intercept |
ar1 |
| 1 |
-0.03854 |
0.7628 |
| 2 |
-0.04351 |
0.7580 |
| 3 |
-0.04351 |
0.7580 |
| 4 |
-0.03854 |
0.7628 |
| 5 |
-0.04351 |
0.7580 |
| 6 |
-0.03855 |
0.7628 |
2. Fill Non-Business-Day Gaps with NA
tsi_t <- read_csv("../../data/Fulton.csv") %>%
# mutate(p = exp(LogPrice)) %>%
mutate(t = ymd(Date)) %>%
mutate(p.log = LogPrice) %>%
mutate(i = row_number()) %>%
select(t, i, p.log) %>%
as_tsibble(index = t)
When t is used as the index of tsibble, non-business-day (NBD) gaps will be detected. fill_gaps() can be used to fill NA values for NBD. See Handle implicit missingness with tsibble for details.
tsi_t %>% fill_gaps() %>% head(14) %>% kable_inline()
| t |
i |
p.log |
| 1991-12-02 |
1 |
-0.43078 |
| 1991-12-03 |
2 |
0.00000 |
| 1991-12-04 |
3 |
0.07232 |
| 1991-12-05 |
4 |
0.24714 |
| 1991-12-06 |
5 |
0.66433 |
| 1991-12-07 |
NA |
NA |
| 1991-12-08 |
NA |
NA |
| 1991-12-09 |
6 |
-0.20651 |
| 1991-12-10 |
7 |
-0.11583 |
| 1991-12-11 |
8 |
-0.25987 |
| 1991-12-12 |
9 |
-0.11713 |
| 1991-12-13 |
10 |
-0.34208 |
| 1991-12-14 |
NA |
NA |
| 1991-12-15 |
NA |
NA |
If fill_gaps() is not used, when fable::ARIMA is applied, there will be an error stating that the data contains implicit gaps in time. You should check your data and convert implicit gaps into explicit missing values.
mods[[7]] <- tsi_t %>%
fill_gaps() %>%
model(fable::ARIMA(p.log ~ 1 + pdq(1, 0, 0)))
mods[[7]] %>% tidy() %>% kable_inline()
| .model |
term |
estimate |
std.error |
statistic |
p.value |
| fable::ARIMA(p.log ~ 1 + pdq(1, 0, 0)) |
ar1 |
0.80098 |
0.05130 |
15.614 |
8.903e-30 |
| fable::ARIMA(p.log ~ 1 + pdq(1, 0, 0)) |
constant |
-0.03826 |
0.01836 |
-2.083 |
3.951e-02 |
However, because the existence of NA values, the above result turns out to be different from what we obtained in section 1.
mods[[5]] %>% tidy() %>% kable_inline()
| .model |
term |
estimate |
std.error |
statistic |
p.value |
| fable::ARIMA(p.log ~ 1 + pdq(1, 0, 0)) |
ar1 |
0.75805 |
0.06287 |
12.058 |
6.601e-22 |
| fable::ARIMA(p.log ~ 1 + pdq(1, 0, 0)) |
constant |
-0.04351 |
0.02324 |
-1.872 |
6.379e-02 |
Whether to fill the NBD gaps depends on the context. Forecasting time series with data on weekdays only, CrossValidated. More advanced calendars may be used. Calendarise self-defined date-times (e.g. business days and time) and respect structural missingness.
3. How to Visualize without NBD Gaps Filled
So if we don’t want to fill NBD gaps, a nex index must be added like that in section 1. It is hard to use autoplot() with t specified as x axis. ggplot() must be used.
tsi %>% ggplot() +
geom_line(aes(t, p.log))

When using other functions in feasts, the univaraite time series must be specified.
tsi %>% gg_tsdisplay(p.log)

tsi %>% ACF(p.log) %>%
autoplot()

LS0tCnRpdGxlOiAiSG93IHRvIERlYWwgd2l0aCBOb24tQnVzaW5lc3MtRGF5IEdhcHMiCmF1dGhvcjogIkVkd2FyZCBKLiBYdSAoPGVkeHU5NkBvdXRsb29rLmNvbT4pIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCmRvY3VtZW50Y2xhc3M6IGFydGljbGUKY2xhc3NvcHRpb246IGE0cGFwZXIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGRmX3ByaW50OiBwYWdlZAogICAgZmlnX2NhcHRpb246IG5vCiAgICBmaWdfaGVpZ2h0OiA3LjUKICAgIGZpZ193aWR0aDogMTUKICAgIHNtb290aF9zY3JvbGw6IHllcwogICAgdGhlbWU6IGRlZmF1bHQKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IG5vCmVkaXRvcl9vcHRpb25zOgogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpgYGB7ciwgZWNobz1GfQpybShsaXN0ID0gbHMoKSkKc2V0d2QoIn4vR2l0SHViL1RpZHlTaW1TdGF0L2V4YW1wbGVzL0FSSU1BIikKYGBgCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFfQojIyBCYXNpYyBwYWNrYWdlcwpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KG1hZ3JpdHRyKQpsaWJyYXJ5KHRzaWJibGUpCmxpYnJhcnkobHVicmlkYXRlKQojIyBTcGVjaWFsaXplZCBwYWNrYWdlcwpsaWJyYXJ5KGZvcmVjYXN0KQpsaWJyYXJ5KGZhYmxlKQpsaWJyYXJ5KGZlYXN0cykKbGlicmFyeShmYWJsZXRvb2xzKQpsaWJyYXJ5KHN0YXRzKQpsaWJyYXJ5KGdldHMpCmBgYAoKIyMgMS4gRGlmZmVyZW50IEZ1bmN0aW9ucyBmb3IgQXV0b3JlZ3Jlc3NpdmUgTW9kZWxzIAoKQSBuZXcgaW5kZXggYGlgIGlzIHVzZWQuCgpgYGB7ciwgd2FybmluZz1GLCBtZXNzYWdlPUYsIGVjaG89VH0KdHNpIDwtIHJlYWRfY3N2KCIuLi8uLi9kYXRhL0Z1bHRvbi5jc3YiKSAlPiUKICAjIG11dGF0ZShwID0gZXhwKExvZ1ByaWNlKSkgJT4lIAogIG11dGF0ZSh0ID0geW1kKERhdGUpKSAlPiUKICBtdXRhdGUocC5sb2cgPSBMb2dQcmljZSkgJT4lCiAgbXV0YXRlKGkgPSByb3dfbnVtYmVyKCkpICU+JQogIHNlbGVjdChpLCB0LCBwLmxvZykgJT4lCiAgYXNfdHNpYmJsZShpbmRleCA9IGkpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RiwgZWNobz1ULCBjb2xsYXBzZT1UfQptb2RzIDwtIGxpc3QoKQoKbW9kc1tbMV1dIDwtIHRzaSAlPiUKICB7LiRwLmxvZ30gJT4lCiAgYXIub2xzKGFpYyA9IEZBTFNFLCBvcmRlci5tYXggPSAxLCBkZW1lYW4gPSBGLCBpbnRlcmNlcHQgPSBUKQoKbW9kc1tbMl1dIDwtIHRzaSAlPiUKICB7LiRwLmxvZ30gJT4lCiAgYXIubWxlKGFpYyA9IEZBTFNFLCBvcmRlci5tYXggPSAxLCBkZW1lYW4gPSBULCBpbnRlcmNlcHQgPSBGKQogICMgVGhlcmUgaXMgbm8gd2F5IGZvciBgYXIubWxlYCB0byBlc3RpbWF0ZSB0aGUgaW50ZXJjZXB0IGRpcmVjdGx5LgoKbW9kc1tbM11dIDwtIHRzaSAlPiUKICB7LiRwLmxvZ30gJT4lCiAgYXJpbWEob3JkZXIgPSBjKDEsIDAsIDApLCBpbmNsdWRlLm1lYW4gPSBULCBtZXRob2QgPSAiTUwiKQogICMgVGhlcmUgaXMgbm8gd2F5IGZvciBgYXJpbWFgIHRvIGVzdGltYXRlIHRoZSBpbnRlcmNlcHQgZGlyZWN0bHkuCgptb2RzW1s0XV0gPC0gdHNpICU+JQogIHsuJHAubG9nfSAlPiUKICBnZXRzOjphcngobWMgPSBULCBhciA9IDEsIG14cmVnID0gTlVMTCwgcXN0YXQub3B0aW9ucyA9IGMoMSwxKSkKCm1vZHNbWzVdXSA8LSB0c2kgJT4lCiAgbW9kZWwoZmFibGU6OkFSSU1BKHAubG9nIH4gMSArIHBkcSgxLCAwLCAwKSkpCgptb2RzW1s2XV0gPC0gdHNpICU+JQogIHsuJHAubG9nfSAlPiUKICBhcmltYShvcmRlciA9IGMoMSwgMCwgMCksIGluY2x1ZGUubWVhbiA9IFQsIG1ldGhvZCA9ICJDU1MiKQpgYGAKCmBgYHtyLCBlY2hvPUZ9CmthYmxlX2lubGluZSA8LSBmdW5jdGlvbih0aSl7CiAgdGkgJT4lCiAgICBtdXRhdGVfaWYoaXMubnVtZXJpYywgZm9ybWF0LCBkaWdpdHMgPSA0KSAlPiUKICAgICMgbXV0YXRlX2lmKGlzLm51bWVyaWMsIHJvdW5kLCA0KSAlPiUKICAgIGthYmxlKCkgJT4lCiAgICBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGLCAKICAgICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJjb25kZW5zZWQiLCAicmVzcG9uc2l2ZSIpKQp9CmBgYAoKYGBge3J9CnRpYmJsZSgKICBod2lfbW9kcyA9IDE6NiwKICBpbnRlcmNlcHQgPSBjKAogICAgbW9kc1tbMV1dJHguaW50ZXJjZXB0LCAKICAgIGFzLmRvdWJsZShtb2RzW1syXV0keC5tZWFuKSAqICgxIC0gYXMuZG91YmxlKG1vZHNbWzJdXSRhcikpLCAKICAgIGFzLmRvdWJsZShtb2RzW1szXV0kY29lZlsyXSAqICgxIC0gbW9kc1tbM11dJGNvZWZbMV0pKSwgCiAgICBtb2RzW1s0XV0kY29lZmZpY2llbnRzWzFdLCAKICAgIGFzLmRvdWJsZShjb2VmKG1vZHNbWzVdXSlbMiwgM10pLCAKICAgIGFzLmRvdWJsZShtb2RzW1s2XV0kY29lZlsyXSAqICgxIC0gbW9kc1tbNl1dJGNvZWZbMV0pKQogICAgKSwgCiAgYXIxID0gYygKICAgIG1vZHNbWzFdXSRhclsxXSwgCiAgICBhcy5kb3VibGUobW9kc1tbMl1dJGFyKSwgCiAgICBhcy5kb3VibGUobW9kc1tbM11dJGNvZWZbMV0pLCAKICAgIG1vZHNbWzRdXSRjb2VmZmljaWVudHNbMl0sIAogICAgYXMuZG91YmxlKGNvZWYobW9kc1tbNV1dKVsxLCAzXSksIAogICAgYXMuZG91YmxlKG1vZHNbWzZdXSRjb2VmWzFdKQogICAgKQogICkgJT4lCiAga2FibGVfaW5saW5lKCkKYGBgCgojIyAyLiBGaWxsIE5vbi1CdXNpbmVzcy1EYXkgR2FwcyB3aXRoIGBOQWAKCmBgYHtyLCB3YXJuaW5nPUYsIG1lc3NhZ2U9RiwgZWNobz1UfQp0c2lfdCA8LSByZWFkX2NzdigiLi4vLi4vZGF0YS9GdWx0b24uY3N2IikgJT4lCiAgIyBtdXRhdGUocCA9IGV4cChMb2dQcmljZSkpICU+JSAKICBtdXRhdGUodCA9IHltZChEYXRlKSkgJT4lCiAgbXV0YXRlKHAubG9nID0gTG9nUHJpY2UpICU+JQogIG11dGF0ZShpID0gcm93X251bWJlcigpKSAlPiUKICBzZWxlY3QodCwgaSwgcC5sb2cpICU+JQogIGFzX3RzaWJibGUoaW5kZXggPSB0KQpgYGAKCldoZW4gYHRgIGlzIHVzZWQgYXMgdGhlIGluZGV4IG9mIGB0c2liYmxlYCwgbm9uLWJ1c2luZXNzLWRheSAoTkJEKSBnYXBzIHdpbGwgYmUgZGV0ZWN0ZWQuIGBmaWxsX2dhcHMoKWAgY2FuIGJlIHVzZWQgdG8gZmlsbCBgTkFgIHZhbHVlcyBmb3IgTkJELiBTZWUgW0hhbmRsZSBpbXBsaWNpdCBtaXNzaW5nbmVzcyB3aXRoIHRzaWJibGVdKGh0dHBzOi8vdHNpYmJsZS50aWR5dmVydHMub3JnL2FydGljbGVzL2ltcGxpY2l0LW5hLmh0bWwpIGZvciBkZXRhaWxzLgoKYGBge3J9CnRzaV90ICU+JSBmaWxsX2dhcHMoKSAlPiUgaGVhZCgxNCkgJT4lIGthYmxlX2lubGluZSgpCmBgYAoKSWYgYGZpbGxfZ2FwcygpYCBpcyBub3QgdXNlZCwgd2hlbiBgZmFibGU6OkFSSU1BYCBpcyBhcHBsaWVkLCB0aGVyZSB3aWxsIGJlIGFuIGVycm9yIHN0YXRpbmcgdGhhdCB0aGUgZGF0YSBjb250YWlucyBpbXBsaWNpdCBnYXBzIGluIHRpbWUuIFlvdSBzaG91bGQgY2hlY2sgeW91ciBkYXRhIGFuZCBjb252ZXJ0IGltcGxpY2l0IGdhcHMgaW50byBleHBsaWNpdCBtaXNzaW5nIHZhbHVlcy4KCmBgYHtyfQptb2RzW1s3XV0gPC0gdHNpX3QgJT4lCiAgZmlsbF9nYXBzKCkgJT4lCiAgbW9kZWwoZmFibGU6OkFSSU1BKHAubG9nIH4gMSArIHBkcSgxLCAwLCAwKSkpCgptb2RzW1s3XV0gJT4lIHRpZHkoKSAlPiUga2FibGVfaW5saW5lKCkKYGBgCgpIb3dldmVyLCBiZWNhdXNlIHRoZSBleGlzdGVuY2Ugb2YgYE5BYCB2YWx1ZXMsIHRoZSBhYm92ZSByZXN1bHQgdHVybnMgb3V0IHRvIGJlIGRpZmZlcmVudCBmcm9tIHdoYXQgd2Ugb2J0YWluZWQgaW4gc2VjdGlvbiAxLgoKYGBge3J9Cm1vZHNbWzVdXSAlPiUgdGlkeSgpICU+JSBrYWJsZV9pbmxpbmUoKQpgYGAKCldoZXRoZXIgdG8gZmlsbCB0aGUgTkJEIGdhcHMgZGVwZW5kcyBvbiB0aGUgY29udGV4dC4gW0ZvcmVjYXN0aW5nIHRpbWUgc2VyaWVzIHdpdGggZGF0YSBvbiB3ZWVrZGF5cyBvbmx5LCBDcm9zc1ZhbGlkYXRlZF0oaHR0cHM6Ly9zdGF0cy5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvMzI3MzQzL2ZvcmVjYXN0aW5nLXRpbWUtc2VyaWVzLXdpdGgtZGF0YS1vbi13ZWVrZGF5cy1vbmx5KS4gTW9yZSBhZHZhbmNlZCBjYWxlbmRhcnMgbWF5IGJlIHVzZWQuIFtDYWxlbmRhcmlzZSBzZWxmLWRlZmluZWQgZGF0ZS10aW1lcyAoZS5nLiBidXNpbmVzcyBkYXlzIGFuZCB0aW1lKSBhbmQgcmVzcGVjdCBzdHJ1Y3R1cmFsIG1pc3NpbmduZXNzXShodHRwczovL2dpdGh1Yi5jb20vdGlkeXZlcnRzL3RzaWJibGUvaXNzdWVzLzE4KS4KCgojIyAzLiBIb3cgdG8gVmlzdWFsaXplIHdpdGhvdXQgTkJEIEdhcHMgRmlsbGVkCgpTbyBpZiB3ZSBkb24ndCB3YW50IHRvIGZpbGwgTkJEIGdhcHMsIGEgbmV4IGluZGV4IG11c3QgYmUgYWRkZWQgbGlrZSB0aGF0IGluIHNlY3Rpb24gMS4gSXQgaXMgaGFyZCB0byB1c2UgYGF1dG9wbG90KClgIHdpdGggYHRgIHNwZWNpZmllZCBhcyB4IGF4aXMuIGBnZ3Bsb3QoKWAgbXVzdCBiZSB1c2VkLgoKYGBge3J9CnRzaSAlPiUgZ2dwbG90KCkgKwogIGdlb21fbGluZShhZXModCwgcC5sb2cpKQpgYGAKCldoZW4gdXNpbmcgb3RoZXIgZnVuY3Rpb25zIGluIGBmZWFzdHNgLCB0aGUgdW5pdmFyYWl0ZSB0aW1lIHNlcmllcyBtdXN0IGJlIHNwZWNpZmllZC4KCmBgYHtyfQp0c2kgJT4lIGdnX3RzZGlzcGxheShwLmxvZykKYGBgCgpgYGB7cn0KdHNpICU+JSBBQ0YocC5sb2cpICU+JQogIGF1dG9wbG90KCkKYGBgCgoKCgo=