library(tidyverse)
library(readxl)
library(ggplot2)
library(lubridate)
library(writexl)
library(magrittr)
1, Tidy Data
Here is the history data about monthly electricity demand satisfied by non-renewable energy technologies from 2013 to 2017, which are downloaded from Malta National Statistics Office.
head(ti)
ti %>%
mutate(month = month(.$date)) %>%
mutate(year = as.character(year(.$date))) %>%
ggplot() +
geom_line(mapping = aes(x = month, y = demand, color = year))

ti %>%
ggplot() +
geom_line(mapping = aes(x = date, y = demand)) +
labs(
title = "Monthly Electricity Demand from Non-Renewables",
subtitle = "in Malta from 2013 to 2017",
y = "Electricity Demand from Non-Renewables (MWh)",
x = "Index (Month)"
)

2, Decomposition
ts <-
ts(ti$demand, frequency = 12)
li_decomp <-
ts %>%
decompose(type = c("multiplicative"), filter = NULL)
The seasonal compoents is the most important part, and it’s shown in the following figure.
ts <-
ts(ti$demand, frequency = 12)
li_decomp <-
ts %>%
decompose(type = c("multiplicative"), filter = NULL)
ti %>%
mutate(coef_decomp = as.numeric(li_decomp$seasonal)) %>%
ggplot() +
geom_line(mapping = aes(x = date, y = coef_decomp)) +
labs(
title = "Seasonal Coefficients of Decomposition",
subtitle = "for Monthly Non-Re E-Demand in Malta from 2013 to 2017",
y = "Seasonal Coefficients",
x = "Index (Month)"
)

The random component is checked using ACF and PACF.
acf(li_decomp$random, na.action = na.pass)

pacf(li_decomp$random, na.action = na.pass)

We can say that the random component can be treated as white noise.
3, Model Trending Component using Linear Regression
acf(li_decomp$trend, na.action = na.pass)

pacf(li_decomp$trend, na.action = na.pass)

arima(as.ts(li_decomp$trend))
Call:
arima(x = as.ts(li_decomp$trend))
Coefficients:
intercept
178153.1495
s.e. 337.1318
sigma^2 estimated as 5455566: log likelihood = -440.4, aic = 884.8
Though there is some correlation in ACF of the trending component, the “arima” function shows that no benefit, which is the same as expected becuase the length of the sampling is one month. So linear regression is used.
df_trend <- data.frame(x = 1:length(li_decomp$trend), y = li_decomp$trend)
lm_trend <- lm(y ~ x, df_trend)
par(mfrow = c(2, 2))
plot(lm_trend)

The illustration of linear regression anad forecast of trending component is shown in the following figure.
par(mfrow = c(1, 1))
plot(
predict(
lm_trend, newdata = data.frame(x = c(1:(length(df_trend$x) + 12 * 10)))
)
)
lines(df_trend$x, df_trend$y)

4, Forecast
trend_new <- predict(
lm_trend, newdata = data.frame(
x = c((length(df_trend$x) + 1):(length(df_trend$x) + 12 * 20))
)
)
seasonal_new <- rep(li_decomp$seasonal[1:12], 20)
ti_new <-
tibble(
index = 1:(12 * 20), demand = trend_new * seasonal_new # multiplicative
) %>%
mutate(date = rep(ti$date[60], length(.$index)))
for (i in 1:length(ti_new$index)) {
month(ti_new$date[i]) = i + month(ti$date[60])
}
ti_new %<>%
select(date, demand) %>%
mutate(observation = rep(FALSE, length(.$date)))
ti_fore <- ti %>%
bind_rows(ti_new)
ti_fore %>%
ggplot() +
geom_line(mapping = aes(x = date, y = demand, color = observation)) +
labs(title = "Forecast of Monthly Electricity Demand from Non-Renewables",
subtitle = "in Malta from 2018 to 2037 using Data from 2013 to 2017",
y = "Electricity Demand from Non-Renewables (MWh)",
x = "Index (Month)")

LS0tCnRpdGxlOiAiRm9yZWNhc3Qgb2YgRWxlY3RyaWNpdHkgRGVtYW5kIGluIE1hbHRhIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciwgaW5jbHVkZSA9IEZBTFNFfQpybShsaXN0ID0gbHMoKSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGNvbGxhcHNlID0gVFJVRSwKICBjb21tZW50ID0gIiM+IiwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcuYXNwID0gOS8xNiwKICBmaWcud2lkdGggPSAxMCwKICB3YXJuaW5nID0gRkFMU0UKKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkod3JpdGV4bCkKbGlicmFyeShtYWdyaXR0cikKYGBgCgojIyAxLCBUaWR5IERhdGEKCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQp0aSA8LQogIHJlYWR4bDo6cmVhZF9leGNlbCgifi9HaXRIdWIvRW5lcmd5U3RvcmFnZS9kZW1hbmQtZm9yZWNhc3QvZGVtYW5kLXdpdGhvdXQtcmVuZXdhYmxlcy54bHN4IikgJT4lCiAgbXV0YXRlKG1vbnRoID0gMToxMikgJT4lCiAgZ2F0aGVyKC1tb250aCwga2V5ID0gInllYXIiLCB2YWx1ZSA9ICJkZW1hbmQiKSAlPiUKICBtdXRhdGUoeWVhciA9IGFzLm51bWVyaWMoLiR5ZWFyKSkgJT4lCiAgbXV0YXRlKGRhdGUgPSB5bWQoc3ByaW50ZigiJWQtJTAyZC0wMSIsIC4keWVhciwgLiRtb250aCkpKSAlPiUKICBtdXRhdGUob2JzZXJ2YXRpb24gPSByZXAoVFJVRSwgbGVuZ3RoKGRhdGUpKSkgJT4lCiAgc2VsZWN0KGRhdGUsIGRlbWFuZCwgb2JzZXJ2YXRpb24pCmBgYAoKSGVyZSBpcyB0aGUgaGlzdG9yeSBkYXRhIGFib3V0IG1vbnRobHkgZWxlY3RyaWNpdHkgZGVtYW5kIHNhdGlzZmllZCBieSBub24tcmVuZXdhYmxlIGVuZXJneSB0ZWNobm9sb2dpZXMgZnJvbSAyMDEzIHRvIDIwMTcsIHdoaWNoIGFyZSBkb3dubG9hZGVkIGZyb20gTWFsdGEgTmF0aW9uYWwgU3RhdGlzdGljcyBPZmZpY2UuCgpgYGB7cn0KaGVhZCh0aSkKYGBgCgpgYGB7cn0KdGkgJT4lCiAgbXV0YXRlKG1vbnRoID0gbW9udGgoLiRkYXRlKSkgJT4lCiAgbXV0YXRlKHllYXIgPSBhcy5jaGFyYWN0ZXIoeWVhciguJGRhdGUpKSkgJT4lCiAgZ2dwbG90KCkgKwogICAgZ2VvbV9saW5lKG1hcHBpbmcgPSBhZXMoeCA9IG1vbnRoLCB5ID0gZGVtYW5kLCBjb2xvciA9IHllYXIpKQpgYGAKCmBgYHtyfQp0aSAlPiUKICBnZ3Bsb3QoKSArCiAgICBnZW9tX2xpbmUobWFwcGluZyA9IGFlcyh4ID0gZGF0ZSwgeSA9IGRlbWFuZCkpICsKICAgIGxhYnMoCiAgICAgIHRpdGxlID0gIk1vbnRobHkgRWxlY3RyaWNpdHkgRGVtYW5kIGZyb20gTm9uLVJlbmV3YWJsZXMiLAogICAgICBzdWJ0aXRsZSA9ICJpbiBNYWx0YSBmcm9tIDIwMTMgdG8gMjAxNyIsCiAgICAgIHkgPSAiRWxlY3RyaWNpdHkgRGVtYW5kIGZyb20gTm9uLVJlbmV3YWJsZXMgKE1XaCkiLAogICAgICB4ID0gIkluZGV4IChNb250aCkiCiAgICAgICkKYGBgCgojIyAyLCBEZWNvbXBvc2l0aW9uCgpgYGB7cn0KdHMgPC0KICB0cyh0aSRkZW1hbmQsIGZyZXF1ZW5jeSA9IDEyKQoKbGlfZGVjb21wIDwtCiAgdHMgJT4lCiAgZGVjb21wb3NlKHR5cGUgPSBjKCJtdWx0aXBsaWNhdGl2ZSIpLCBmaWx0ZXIgPSBOVUxMKQpgYGAKClRoZSBzZWFzb25hbCBjb21wb2VudHMgaXMgdGhlIG1vc3QgaW1wb3J0YW50IHBhcnQsIGFuZCBpdCdzIHNob3duIGluIHRoZSBmb2xsb3dpbmcgZmlndXJlLgoKYGBge3J9CnRpICU+JQogIG11dGF0ZShjb2VmX2RlY29tcCA9IGFzLm51bWVyaWMobGlfZGVjb21wJHNlYXNvbmFsKSkgJT4lCiAgZ2dwbG90KCkgKwogICAgZ2VvbV9saW5lKG1hcHBpbmcgPSBhZXMoeCA9IGRhdGUsIHkgPSBjb2VmX2RlY29tcCkpICsKICAgIGxhYnMoCiAgICAgIHRpdGxlID0gIlNlYXNvbmFsIENvZWZmaWNpZW50cyBvZiBEZWNvbXBvc2l0aW9uIiwKICAgICAgc3VidGl0bGUgPSAiZm9yIE1vbnRobHkgTm9uLVJlIEUtRGVtYW5kIGluIE1hbHRhIGZyb20gMjAxMyB0byAyMDE3IiwKICAgICAgeSA9ICJTZWFzb25hbCBDb2VmZmljaWVudHMiLAogICAgICB4ID0gIkluZGV4IChNb250aCkiCiAgICAgICkKYGBgCgpUaGUgcmFuZG9tIGNvbXBvbmVudCBpcyBjaGVja2VkIHVzaW5nIEFDRiBhbmQgUEFDRi4KCmBgYHtyfQphY2YobGlfZGVjb21wJHJhbmRvbSwgbmEuYWN0aW9uID0gbmEucGFzcykKYGBgCgpgYGB7cn0KcGFjZihsaV9kZWNvbXAkcmFuZG9tLCBuYS5hY3Rpb24gPSBuYS5wYXNzKQpgYGAKCldlIGNhbiBzYXkgdGhhdCB0aGUgcmFuZG9tIGNvbXBvbmVudCBjYW4gYmUgdHJlYXRlZCBhcyB3aGl0ZSBub2lzZS4KCiMjIDMsIE1vZGVsIFRyZW5kaW5nIENvbXBvbmVudCB1c2luZyBMaW5lYXIgUmVncmVzc2lvbgoKYGBge3J9CmFjZihsaV9kZWNvbXAkdHJlbmQsIG5hLmFjdGlvbiA9IG5hLnBhc3MpCmBgYAoKYGBge3J9CnBhY2YobGlfZGVjb21wJHRyZW5kLCBuYS5hY3Rpb24gPSBuYS5wYXNzKQpgYGAKCmBgYHtyfQphcmltYShhcy50cyhsaV9kZWNvbXAkdHJlbmQpKQpgYGAKClRob3VnaCB0aGVyZSBpcyBzb21lIGNvcnJlbGF0aW9uIGluIEFDRiBvZiB0aGUgdHJlbmRpbmcgY29tcG9uZW50LCB0aGUgImFyaW1hIiBmdW5jdGlvbiBzaG93cyB0aGF0IG5vIGJlbmVmaXQsIHdoaWNoIGlzIHRoZSBzYW1lIGFzIGV4cGVjdGVkIGJlY3Vhc2UgdGhlIGxlbmd0aCBvZiB0aGUgc2FtcGxpbmcgaXMgb25lIG1vbnRoLiBTbyBsaW5lYXIgcmVncmVzc2lvbiBpcyB1c2VkLgoKYGBge3J9CmRmX3RyZW5kIDwtIGRhdGEuZnJhbWUoeCA9IDE6bGVuZ3RoKGxpX2RlY29tcCR0cmVuZCksIHkgPSBsaV9kZWNvbXAkdHJlbmQpCmxtX3RyZW5kIDwtIGxtKHkgfiB4LCBkZl90cmVuZCkKCnBhcihtZnJvdyA9IGMoMiwgMikpCnBsb3QobG1fdHJlbmQpCmBgYAoKVGhlIGlsbHVzdHJhdGlvbiBvZiBsaW5lYXIgcmVncmVzc2lvbiBhbmFkIGZvcmVjYXN0IG9mIHRyZW5kaW5nIGNvbXBvbmVudCBpcyBzaG93biBpbiB0aGUgZm9sbG93aW5nIGZpZ3VyZS4KCmBgYHtyfQpwYXIobWZyb3cgPSBjKDEsIDEpKQpwbG90KAogIHByZWRpY3QoCiAgICBsbV90cmVuZCwgbmV3ZGF0YSA9IGRhdGEuZnJhbWUoeCA9IGMoMToobGVuZ3RoKGRmX3RyZW5kJHgpICsgMTIgKiAxMCkpKQogICAgKQogICkKbGluZXMoZGZfdHJlbmQkeCwgZGZfdHJlbmQkeSkKYGBgCgojIyA0LCBGb3JlY2FzdAoKYGBge3J9CnRyZW5kX25ldyA8LSBwcmVkaWN0KAogIGxtX3RyZW5kLCBuZXdkYXRhID0gZGF0YS5mcmFtZSgKICAgIHggPSBjKChsZW5ndGgoZGZfdHJlbmQkeCkgKyAxKToobGVuZ3RoKGRmX3RyZW5kJHgpICsgMTIgKiAyMCkpCiAgICApCiAgKQpzZWFzb25hbF9uZXcgPC0gcmVwKGxpX2RlY29tcCRzZWFzb25hbFsxOjEyXSwgMjApCgp0aV9uZXcgPC0KICB0aWJibGUoCiAgICBpbmRleCA9IDE6KDEyICogMjApLCBkZW1hbmQgPSB0cmVuZF9uZXcgKiBzZWFzb25hbF9uZXcgICMgbXVsdGlwbGljYXRpdmUKICAgICkgJT4lCiAgbXV0YXRlKGRhdGUgPSByZXAodGkkZGF0ZVs2MF0sIGxlbmd0aCguJGluZGV4KSkpCgpmb3IgKGkgaW4gMTpsZW5ndGgodGlfbmV3JGluZGV4KSkgewogIG1vbnRoKHRpX25ldyRkYXRlW2ldKSA9IGkgKyBtb250aCh0aSRkYXRlWzYwXSkKfQoKdGlfbmV3ICU8PiUKICBzZWxlY3QoZGF0ZSwgZGVtYW5kKSAlPiUKICBtdXRhdGUob2JzZXJ2YXRpb24gPSByZXAoRkFMU0UsIGxlbmd0aCguJGRhdGUpKSkKCnRpX2ZvcmUgPC0gdGkgJT4lCiAgYmluZF9yb3dzKHRpX25ldykKCnRpX2ZvcmUgJT4lCiAgZ2dwbG90KCkgKwogICAgZ2VvbV9saW5lKG1hcHBpbmcgPSBhZXMoeCA9IGRhdGUsIHkgPSBkZW1hbmQsIGNvbG9yID0gb2JzZXJ2YXRpb24pKSArCiAgICBsYWJzKHRpdGxlID0gIkZvcmVjYXN0IG9mIE1vbnRobHkgRWxlY3RyaWNpdHkgRGVtYW5kIGZyb20gTm9uLVJlbmV3YWJsZXMiLAogICAgICAgICBzdWJ0aXRsZSA9ICJpbiBNYWx0YSBmcm9tIDIwMTggdG8gMjAzNyB1c2luZyBEYXRhIGZyb20gMjAxMyB0byAyMDE3IiwKICAgICAgICAgeSA9ICJFbGVjdHJpY2l0eSBEZW1hbmQgZnJvbSBOb24tUmVuZXdhYmxlcyAoTVdoKSIsCiAgICAgICAgIHggPSAiSW5kZXggKE1vbnRoKSIpCmBgYAoK