Data yang digunakan adalah volume produksi air minum PDAM Kabupaten Serang bulanan, Januari 2022–Desember 2024 (ribu m³/bulan), sebanyak 36 observasi. Analisis dilakukan dengan dekomposisi deret waktu aditif, yaitu
\[Y_t = T_t + S_t + R_t,\]
dengan \(T_t\) komponen tren, \(S_t\) komponen musiman, dan \(R_t\) komponen residual. Model aditif sesuai apabila amplitudo fluktuasi musiman relatif konstan meskipun level data berubah. Dekomposisi multiplikatif ditambahkan di akhir sebagai pembanding.
# DATA
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)
# 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)
}
Vektor produksi berisi 36 nilai yang disusun berurutan
per tahun. Vektor lab dan fungsi plot_ts()
hanya berfungsi mengatur label sumbu waktu agar tampil sebagai bulan dan
tahun, serta tidak memengaruhi hasil perhitungan.
ts dan Dekomposisi Aditifts_air <- ts(produksi, start = c(2022, 1), frequency = 12)
dek_add <- decompose(ts_air, type = "additive")
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))
Objek ts_air dibuat dengan
start = c(2022, 1) dan frequency = 12 sehingga
R membaca data sebagai deret bulanan. Fungsi decompose()
menguraikan data menjadi tiga komponen. Plot data asli memperlihatkan
kenaikan level yang jelas dari tahun ke tahun disertai gelombang yang
berulang setiap 12 bulan. Keduanya berhasil dipisahkan menjadi tren yang
naik mulus (panel kedua) dan pola musiman yang berulang (panel ketiga).
Sisa variasi yang tidak dijelaskan keduanya ada pada panel residual.
Komponen tren bernilai NA pada enam bulan pertama
(Jan–Jun 2022) dan enam bulan terakhir (Jul–Des 2024). Hal ini wajar
karena decompose() menghitung tren dengan rata-rata
bergerak terpusat orde 12 (2×12 MA) yang memerlukan 6 data di setiap
sisi, sehingga tren hanya tersedia untuk 24 titik (Jul 2022–Jun
2024).
# 2. Komponen tren + uji kenaikan
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
plot_ts(dek_add$trend, "Komponen Tren (Aditif)", "Ribu m3", col = "blue", lwd = 2)
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
rata_tahun <- tapply(produksi, rep(2022:2024, each = 12), mean)
rata_tahun
## 2022 2023 2024
## 426.5000 458.5833 489.7500
rata_tahun["2023"] / rata_tahun["2022"] - 1
## 2023
## 0.0752247
rata_tahun["2024"] / rata_tahun["2023"] - 1
## 2024
## 0.06796293
rata_tahun["2024"] / rata_tahun["2022"] - 1
## 2024
## 0.1483001
Produksi air minum PDAM Kabupaten Serang menunjukkan tren naik yang jelas dan konsisten, berdasarkan tiga bukti berikut.
Komponen tren sudah dihaluskan dengan rata-rata bergerak sehingga titik-titiknya saling bergantung. Oleh karena itu, p-value dan \(R^2\) pada regresi di atas sebaiknya dibaca sebagai ukuran deskriptif, bukan sebagai uji inferensial yang ketat. Kesimpulan tren naik tetap kuat karena didukung oleh nilai tren dan rata-rata tahunan itu sendiri.
# 3. Indeks musiman (12 bulan)
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)
Pada model aditif, indeks musiman menyatakan selisih rata-rata produksi suatu bulan terhadap garis tren dalam satuan ribu m³. Jumlah ke-12 indeks sama dengan nol karena sudah dinormalkan.
| Kelompok | Bulan (indeks musiman) |
|---|---|
| Di atas tren | Juli (+27,75), Juni (+21,21), Agustus (+9,73), Mei (+7,84) |
| Sekitar tren | April (−0,06), Februari (−1,75), Januari (−4,54) |
| Di bawah tren | Desember (−5,31), September (−7,35), Maret (−11,92), Oktober (−15,48), November (−20,12) |
Penjelasan berikut merupakan hipotesis yang belum diuji secara statistik.
# 4. Residual aditif
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 tampak berfluktuasi acak di sekitar nol, dengan alasan berikut.
Pemeriksaan visual dapat dilengkapi dengan uji autokorelasi untuk memastikan tidak ada pola yang tersisa pada residual.
acf(res_add, main = "ACF Residual (Aditif)")
Box.test(res_add, lag = 6, type = "Ljung-Box")
##
## Box-Ljung test
##
## data: res_add
## X-squared = 6.29, df = 6, p-value = 0.3915
Nilai ACF pada lag 1–6 berada di dalam batas kepercayaan sekitar ±0,41, dan uji Ljung-Box (lag 6) menghasilkan p-value sekitar 0,39 (> 0,05). Dengan demikian tidak ada bukti autokorelasi pada residual, sehingga kesimpulan bahwa residual bersifat acak diperkuat. (Nilai di atas berasal dari perhitungan ulang di luar kode awal. Periksa kembali dengan hasil keluaran R Anda.)
# DEKOMPOSISI MULTIPLIKATIF
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
# PERBANDINGAN ADITIF vs MULTIPLIKATIF
# 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))
Setelah galat dinyatakan dalam satuan asli (ribu m³), simpangan baku galat model aditif (0,486) sedikit lebih kecil daripada model multiplikatif (0,561). Selisih nilai maksimum dan minimum per tahun juga relatif stabil (50, 50, dan 53 ribu m³) walaupun level produksi naik. Ini menunjukkan amplitudo musiman tidak membesar mengikuti kenaikan level, sehingga model aditif lebih tepat untuk data ini. Pada model multiplikatif, indeks Juli sebesar 1,0626 berarti produksi sekitar 6,26% di atas tren, dan indeks November sebesar 0,9556 berarti sekitar 4,44% di bawah tren. Bulan tertinggi dan terendahnya sama dengan model aditif.