produksi <- c(410,415,405,420,430,445,455,440,425,420,418,435,
440,445,438,452,462,478,488,472,458,452,450,468,
470,476,468,483,494,510,521,504,489,483,480,499)
ts_air <- ts(produksi, start = c(2022, 1), frequency = 12)
dek_add <- decompose(ts_air, type = "additive")
# Fungsi plot: sumbu waktu berupa bulan + tahun (mis. "Jan 2023")
bln <- c("Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agu","Sep","Okt","Nov","Des")
idx <- seq(1, 36, by = 3)
lab <- paste(bln[(idx - 1) %% 12 + 1], 2022 + (idx - 1) %/% 12)
plot_ts <- function(y, main, ylab, tipe = "o", ...) {
x_num <- as.numeric(time(y))
y_num <- as.numeric(y)
plot(x_num, y_num, type = tipe, pch = 16, cex = 0.6,
xaxt = "n", xlab = "", ylab = ylab, main = main, ...)
axis(1, at = x_num[idx], labels = lab, las = 2, cex.axis = 0.6)
}
par(mfrow = c(2, 2), mar = c(5, 4, 3, 1))
plot_ts(ts_air, "Data Asli", "Ribu m3", col = "black")
plot_ts(dek_add$trend, "Tren (Aditif)", "Ribu m3", col = "blue", lwd = 2)
plot_ts(dek_add$seasonal,"Musiman (Aditif)", "Ribu m3", col = "darkgreen")
plot_ts(dek_add$random, "Residual (Aditif)", "Ribu m3", col = "red"); abline(h = 0, lty = 2)
par(mfrow = c(1, 1))
Plot data asli naik dari kiri ke kanan dengan gelombang yang berulang tiap tahun, puncaknya di sekitar Juli dan lembahnya di sekitar Oktober sampai November. Plot tren berupa garis yang naik terus dan hampir lurus, mulai dari Juli 2022 dan berakhir di Juni 2024 karena sisanya NA. Plot musiman bentuknya sama persis di setiap tahun, naik turun antara sekitar -20 dan +28 ribu m³, dan itu wajar karena decompose() mengulang 12 indeks yang sama. Plot residual berupa titik-titik kecil di sekitar garis nol (antara -0,9 dan 0,8) tanpa bentuk yang jelas.
print(dek_add$trend)
## Jan Feb Mar Apr May Jun Jul Aug
## 2022 NA NA NA NA NA NA 427.7500 430.2500
## 2023 443.7083 446.4167 449.1250 451.8333 454.5000 457.2083 459.8333 462.3750
## 2024 475.4583 478.1667 480.7917 483.3750 485.9167 488.4583 NA NA
## Sep Oct Nov Dec
## 2022 432.8750 435.5833 438.2500 440.9583
## 2023 464.9167 467.4583 470.0833 472.7500
## 2024 NA NA NA NA
t_idx <- as.numeric(time(dek_add$trend))
ok <- !is.na(dek_add$trend)
summary(lm(dek_add$trend[ok] ~ t_idx[ok]))
##
## Call:
## lm(formula = dek_add$trend[ok] ~ t_idx[ok])
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.2586 -0.1005 -0.0247 0.1009 0.2812
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -6.387e+04 1.108e+02 -576.2 <2e-16 ***
## t_idx[ok] 3.179e+01 5.478e-02 580.3 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1548 on 22 degrees of freedom
## Multiple R-squared: 0.9999, Adjusted R-squared: 0.9999
## F-statistic: 3.368e+05 on 1 and 22 DF, p-value: < 2.2e-16
Tren dihitung dengan center moving average 2x12, sehingga 6 bulan
pertama (Januari sampai Juni 2022) dan 6 bulan terakhir (Juli sampai
Desember 2024) bernilai NA. Nilai tren yang ada dimulai
dari sekitar 427,75 ribu m³ pada Juli 2022 dan terus naik sampai sekitar
488,46 ribu m³ pada Juni 2024, tidak ada bulan yang turun.
Hasil regresi linear pada komponen tren memberi kemiringan sekitar 31,79, jadi tren naik rata-rata 31,79 ribu m³ per tahun. Kenaikan ini signifikan (nilai p-value di bawah 0,05) dan R² sekitar 0,9999, jadi trennya hampir lurus. Dengan begitu, produksi air minum PDAM Kabupaten Serang menunjukkan tren naik
idx_add <- round(dek_add$figure, 3); names(idx_add) <- bln
print(idx_add)
## Jan Feb Mar Apr Mei Jun Jul Agu Sep Okt
## -4.540 -1.748 -11.915 -0.061 7.835 21.210 27.752 9.731 -7.352 -15.477
## Nov Des
## -20.123 -5.311
cat("Tertinggi:", names(which.max(idx_add)), "| Terendah:", names(which.min(idx_add)), "\n")
## Tertinggi: Jul | Terendah: Nov
barplot(idx_add, col = ifelse(idx_add > 0, "steelblue", "tomato"),
main = "Indeks Musiman Aditif", ylab = "Ribu m3"); abline(h = 0)
Indeks musiman aditif menunjukkan selisih produksi tiap bulan terhadap tren, dalam ribu m³. Mei sampai Agustus bernilai positif (Mei 7,84; Juni 21,21; Juli 27,75; Agustus 9,73). Selain bulan itu cenderung bernilai negatif, sedangkan April hampir nol (-0,06). Bulan tertinggi adalah Juli, yaitu 27,75 ribu m³ di atas tren, dan bulan terendah adalah November, yaitu 20,12 ribu m³ di bawah tren.
Hal ini mungkin karena Juni sampai Agustus adalah puncak musim kemarau, jadi kebutuhan air untuk mandi, mencuci, dan keperluan lain naik, dan warga yang biasa memakai sumur lebih bergantung pada PDAM. November sudah masuk awal musim hujan, sehingga warga bisa memakai air hujan dan sumber lain, dan produksi PDAM turun.
res_add <- na.omit(dek_add$random)
summary(res_add) # min, kuartil, median, mean, max
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -0.9184 -0.4184 -0.0434 -0.0434 0.3316 0.8316
sd(res_add) # simpangan baku
## [1] 0.4862621
plot_ts(dek_add$random, "Residual (Aditif)", "Ribu m3", tipe = "o")
abline(h = 0, lty = 2, col = "red")
Residual adalah bagian data yang tidak dijelaskan oleh tren dan musiman, yaitu data asli dikurangi tren dan indeks musiman. Residual hanya ada untuk 24 bulan karena tren punya 12 nilai NA. Ringkasan statistiknya: minimum -0,918, kuartil pertama -0,418, median -0,043, rata-rata -0,043, kuartil ketiga 0,332, dan maksimum 0,832. Rata-rata dan median sama-sama dekat dengan nol, yang menunjukkan model tidak cenderung menaksir terlalu tinggi atau terlalu rendah. Karena keduanya hampir sama, sebaran residual juga relatif simetris. Semua residual hanya berkisar antara -0,92 dan 0,83 ribu m³, padahal rata-rata produksi sekitar 458,28 ribu m³. Di plot, titik-titik residual naik turun di sekitar garis nol dan tidak membentuk pola tertentu. Jadi residual tampak berfluktuasi acak di sekitar nol. Ini berarti tren dan musiman sudah menjelaskan hampir semua pola data, sehingga model aditif cocok dipakai.
dek_mul <- decompose(ts_air, type = "multiplicative")
par(mfrow = c(2, 2), mar = c(5, 4, 3, 1))
plot_ts(ts_air, "Data Asli", "Ribu m3", col = "black")
plot_ts(dek_mul$trend, "Tren (Multiplikatif)", "Ribu m3", col = "blue")
plot_ts(dek_mul$seasonal, "Musiman (Multiplikatif)", "Indeks", col = "darkgreen")
plot_ts(dek_mul$random, "Residual (Multiplikatif)","Rasio", col = "red")
abline(h = 1, lty = 2)
par(mfrow = c(1, 1))
idx_mul <- round(dek_mul$figure, 4); names(idx_mul) <- bln
print(idx_mul)
## Jan Feb Mar Apr Mei Jun Jul Agu Sep Okt Nov
## 0.9902 0.9963 0.9744 0.9999 1.0167 1.0449 1.0626 1.0218 0.9836 0.9657 0.9556
## Des
## 0.9883
res_mul <- na.omit(dek_mul$random)
summary(res_mul)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.9981 0.9989 0.9999 0.9999 1.0009 1.0017
sd(res_mul)
## [1] 0.001249183
Pada model multiplikatif, data dianggap sebagai tren x musiman x residual. Plot data asli dan tren sama dengan model aditif karena trennya dihitung dengan moving average yang sama, yaitu naik hampir lurus. Perbedaannya ada pada indeks musiman, yang berupa rasio terhadap tren dengan rata-rata 1, sehingga sumbu plot musimannya berkisar sekitar 0,956 sampai 1,063. Bentuk gelombangnya sama dengan model aditif, dengan puncak di Juli dan lembah di November. Indeks tertinggi adalah Juli (1,0626), artinya produksi Juli sekitar 6,3% di atas tren, diikuti Juni (1,0449) dan Agustus (1,0218). Indeks terendah adalah November (0,9556), yaitu sekitar 4,4% di bawah tren, diikuti Oktober (0,9657) dan Maret (0,9744). Urutan bulan tinggi dan rendahnya sama dengan model aditif, sehingga kesimpulan tentang pola musiman tidak berubah.
Residual multiplikatif berupa rasio yang seharusnya berada di sekitar 1. Pada plotnya, titik-titik residual naik turun di sekitar garis 1 tanpa tren atau gelombang yang jelas. Nilainya berkisar 0,998 sampai 1,0017 dengan rata-rata dan median sekitar 0,9999 dan simpangan baku 0,0012. Artinya, galat model hanya sekitar 0,12% dari nilai yang dijelaskan, dan residualnya berfluktuasi acak di sekitar 1.
# 1. Galat dalam satuan asli (ribu m3) supaya kedua model sebanding
fit_add <- dek_add$trend + dek_add$seasonal
fit_mul <- dek_mul$trend * dek_mul$seasonal
gal_add <- na.omit(ts_air - fit_add) # sama dengan residual aditif
gal_mul <- na.omit(ts_air - fit_mul)
perbandingan <- rbind(
Aditif = c(Rata2 = mean(gal_add), SimpBaku = sd(gal_add)),
Multiplikatif = c(Rata2 = mean(gal_mul), SimpBaku = sd(gal_mul))
)
print(round(perbandingan, 4))
## Rata2 SimpBaku
## Aditif -0.0434 0.4863
## Multiplikatif -0.0492 0.5613
# 2. Fluktuasi musiman per tahun
selisih <- tapply(produksi, rep(2022:2024, each = 12), function(v) max(v) - min(v))
print(selisih)
## 2022 2023 2024
## 50 50 53
# 3. Plot residual berdampingan
par(mfrow = c(1, 2), mar = c(5, 4, 3, 1))
plot_ts(dek_add$random, "Residual Aditif", "Ribu m3", tipe = "o"); abline(h = 0, lty = 2, col = "red")
plot_ts(ts_air - fit_mul, "Galat Multiplikatif", "Ribu m3", tipe = "o"); abline(h = 0, lty = 2, col = "red")
par(mfrow = c(1, 1))
# rata-rata
rata_tahun <- tapply(produksi, rep(2022:2024, each = 12), mean)
rata_tahun
## 2022 2023 2024
## 426.5000 458.5833 489.7500
rata_tahun["2024"] / rata_tahun["2022"] - 1 # sekitar 0.148
## 2024
## 0.1483001
Rata-rata galat kedua model sama-sama dekat nol (aditif -0,043; multiplikatif -0,049). Simpangan baku galat aditif (0,486) sedikit lebih kecil daripada multiplikatif (0,561), jadi model aditif sedikit lebih dekat ke data.
Selisih nilai tertinggi dan terendah tiap tahun adalah 50 (2022), 50 (2023), dan 53 (2024). Besar fluktuasi musimannya hampir sama dari tahun ke tahun, padahal level produksi naik. Ini sesuai dengan asumsi model aditif, yaitu besar fluktuasi musiman tidak ikut naik saat level data naik. Kalau polanya multiplikatif, fluktuasinya akan makin besar mengikuti tren.
Perbedaan kedua model kecil karena rata-rata produksi hanya naik sekitar 15% dari 2022 ke 2024, sehingga plot residual keduanya mirip. Kesimpulannya, dekomposisi aditif sedikit lebih tepat untuk data ini. Model multiplikatif baru lebih cocok kalau fluktuasi musiman ikut membesar pada periode yang lebih panjang.