library(knitr)
library(kableExtra)
library(ggplot2)
library(zoo)

Berikut adalah data pengungjung :

Jumlah Pengunjung Perpustakaan Daerah Kabupaten Serang, Januari 2023–Juni 2024
Bulan Tahun Jumlah Pengunjung (Orang)
Januari 2023 210
Februari 2023 195
Maret 2023 220
April 2023 205
Mei 2023 230
Juni 2023 215
Juli 2023 240
Agustus 2023 225
September 2023 250
Oktober 2023 235
November 2023 245
Desember 2023 260
Januari 2024 255
Februari 2024 265
Maret 2024 270
April 2024 280
Mei 2024 275
Juni 2024 290

Membuat Plot Data Time Series

# Membuat data untuk plot
data_plot <- data.frame(
  Periode = seq(
    as.Date("2023-01-01"),
    by = "month",
    length.out = nrow(data_pengunjung)
  ),
  Pengunjung = data_pengunjung$Pengunjung
)

# Label bulan
data_plot$Bulan <- c(
  "Jan 2023", "Feb 2023", "Mar 2023", "Apr 2023",
  "Mei 2023", "Jun 2023", "Jul 2023", "Agu 2023",
  "Sep 2023", "Okt 2023", "Nov 2023", "Des 2023",
  "Jan 2024", "Feb 2024", "Mar 2024", "Apr 2024",
  "Mei 2024", "Jun 2024"
)

data_plot$Bulan <- factor(
  data_plot$Bulan,
  levels = data_plot$Bulan
)

# Nilai minimum dan maksimum
nilai_min <- min(data_plot$Pengunjung)
nilai_max <- max(data_plot$Pengunjung)

# Plot
ggplot(data_plot, aes(x = Periode, y = Pengunjung)) +
  
  geom_area(
    fill = "#74B9FF",
    alpha = 0.20
  ) +
  
  geom_line(
    color = "#0984E3",
    linewidth = 1.5
  ) +
  
  geom_point(
    color = "#E84393",
    fill = "white",
    shape = 21,
    size = 4,
    stroke = 1.5
  ) +
  
  geom_text(
    aes(label = Pengunjung),
    vjust = -1.2,
    size = 3.5,
    fontface = "bold"
  ) +
  
  geom_point(
    data = subset(data_plot, Pengunjung == nilai_min),
    color = "#D63031",
    size = 6
  ) +
  
  geom_point(
    data = subset(data_plot, Pengunjung == nilai_max),
    color = "#00B894",
    size = 6
  ) +
  
  labs(
    title = "📚 Perkembangan Jumlah Pengunjung",
    subtitle = "Perpustakaan Daerah Kabupaten Serang, Januari 2023 – Juni 2024",
    x = "Periode",
    y = "Jumlah Pengunjung (orang)"
  ) +
  
  scale_x_date(
    date_breaks = "1 month",
    date_labels = "%b\n%Y"
  ) +
  
  theme_minimal(base_size = 13) +
  
  theme(
    plot.title = element_text(
      face = "bold",
      size = 20
    ),
    plot.subtitle = element_text(
      size = 11,
      color = "#636E72"
    ),
    axis.title = element_text(
      face = "bold"
    ),
    axis.text.x = element_text(
      angle = 0,
      hjust = 0.5
    ),
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank()
  )

Dari grafik terlihat adanya kecenderungan peningkatan jumlah pengunjung. Meskipun terjadi fluktuasi pada beberapa bulan, nilai pengunjung secara umum bergerak naik, dari 210 orang pada Januari 2023 hingga mencapai 290 orang pada Juni 2024.

Menghintung SMA(3)

Berikut SMA(3)

pengunjung <- c(
  210, 195, 220, 205, 230, 215,
  240, 225, 250, 235, 245, 260,
  255, 265, 270, 280, 275, 290
)

pengunjung_ts <- ts(
  pengunjung,
  start = c(2023, 1),
  frequency = 12
)

# Menghitung SMA(3)
sma3 <- rollmean(
  pengunjung_ts,
  k = 3,
  align = "right",
  fill = NA
)

# Menampilkan hasil SMA(3)
round(sma3, 2)
##         Jan    Feb    Mar    Apr    May    Jun    Jul    Aug    Sep    Oct
## 2023     NA     NA 208.33 206.67 218.33 216.67 228.33 226.67 238.33 236.67
## 2024 253.33 260.00 263.33 271.67 275.00 281.67                            
##         Nov    Dec
## 2023 243.33 246.67
## 2024

Perbandingan plot Data Asli dan SMA(3)

ts.plot(
  pengunjung_ts,
  sma3,
  col = c("#E84393", "#0984E3"),
  lwd = c(3, 3),
  lty = c(1, 2),
  main = "Data Aktual vs SMA(3)",
  xlab = "Tahun",
  ylab = "Jumlah Pengunjung (orang)"
)
legend(
  "topleft",
  legend = c("Data Aktual", "SMA(3)"),
  col = c("#E84393", "#0984E3"),
  lwd = 3,
  lty = c(1, 2),
  bty = "n"
)

Membandingan 6 bulan terakhir

Enam bulan terakhir adalah Januari–Juni 2024.

data_6bulan <- data.frame(
  Periode = seq(
    as.Date("2024-01-01"),
    by = "month",
    length.out = 6
  ),
  Aktual = c(255, 265, 270, 280, 275, 290),
  SMA3 = c(253.33, 260.00, 263.33, 271.67, 275.00, 281.67)
)
ggplot(data_6bulan, aes(x = Periode)) +
  geom_line(
    aes(y = Aktual, color = "Data Aktual"),
    linewidth = 1.3
  ) +
  geom_point(
    aes(y = Aktual, color = "Data Aktual"),
    size = 3.5
  ) +
  geom_line(
    aes(y = SMA3, color = "SMA(3)"),
    linewidth = 1.3,
    linetype = "dashed"
  ) +
  geom_point(
    aes(y = SMA3, color = "SMA(3)"),
    size = 3
  ) +
  labs(
    title = "Data Aktual vs SMA(3)",
    subtitle = "6 Bulan Terakhir: Januari–Juni 2024",
    x = "Bulan",
    y = "Jumlah Pengunjung (orang)",
    color = NULL
  ) +
  scale_x_date(
    breaks = data_6bulan$Periode,
    labels = format(data_6bulan$Periode, "%b\n%Y")
  ) +
  scale_color_manual(
    values = c(
      "Data Aktual" = "#E84393",
      "SMA(3)" = "#0984E3"
    )
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(
      face = "bold",
      size = 18
    ),
    plot.subtitle = element_text(
      size = 11
    ),
    axis.title = element_text(
      face = "bold"
    ),
    axis.text.x = element_text(
      size = 10,
      lineheight = 0.9
    ),
    legend.position = "top",
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank()
  )

Berdasarkan plot enam bulan terakhir (Januari–Juni 2024), terlihat bahwa SMA(3) mengikuti pola pergerakan data aktual tetapi menghasilkan garis yang lebih halus. SMA(3) cenderung berada di bawah data aktual ketika jumlah pengunjung mengalami peningkatan sehingga menunjukkan adanya keterlambatan (lag). Hal ini terlihat pada Juni 2024, ketika data aktual mencapai 290 orang sedangkan SMA(3) hanya sebesar 281,67 orang. Dengan demikian SMA(3) dapat menggambarkan kecenderungan data, tetapi kurang responsif terhadap kenaikan data aktual secara cepat.

Menghitung Double Moving Average dengan m = 3

pengunjung <- c(
  210, 195, 220, 205, 230, 215,
  240, 225, 250, 235, 245, 260,
  255, 265, 270, 280, 275, 290
)
pengunjung_ts <- ts(
  pengunjung,
  start = c(2023, 1),
  frequency = 12
)
m <- 3
Mp <- rollmean(
  pengunjung_ts,
  k = m,
  align = "right",
  fill = NA
)
Mpp <- rollmean(
  Mp,
  k = m,
  align = "right",
  fill = NA
)
a_t <- 2 * Mp - Mpp
b_t <- (2 / (m - 1)) * (Mp - Mpp)
hasil_dma <- cbind(
  Data_Asli = pengunjung_ts,
  M_t_1 = Mp,
  M_t_2 = Mpp,
  a_t = a_t,
  b_t = b_t
)

round(hasil_dma, 2)
##          Data_Asli  M_t_1  M_t_2    a_t  b_t
## Jan 2023       210     NA     NA     NA   NA
## Feb 2023       195     NA     NA     NA   NA
## Mar 2023       220 208.33     NA     NA   NA
## Apr 2023       205 206.67     NA     NA   NA
## May 2023       230 218.33 211.11 225.56 7.22
## Jun 2023       215 216.67 213.89 219.44 2.78
## Jul 2023       240 228.33 221.11 235.56 7.22
## Aug 2023       225 226.67 223.89 229.44 2.78
## Sep 2023       250 238.33 231.11 245.56 7.22
## Oct 2023       235 236.67 233.89 239.44 2.78
## Nov 2023       245 243.33 239.44 247.22 3.89
## Dec 2023       260 246.67 242.22 251.11 4.44
## Jan 2024       255 253.33 247.78 258.89 5.56
## Feb 2024       265 260.00 253.33 266.67 6.67
## Mar 2024       270 263.33 258.89 267.78 4.44
## Apr 2024       280 271.67 265.00 278.33 6.67
## May 2024       275 275.00 270.00 280.00 5.00
## Jun 2024       290 281.67 276.11 287.22 5.56

Karena membutuhkan 3 observasi untuk \(M'_t\) dan kemudian 3 nilai \(M'_t\) untuk \(M''_t\), maka \(M''_t\) baru tersedia mulai Mei 2023.

Interpretasi \(a_t\) dan \(b_t\)

Menurut materi, \(a_t\) digunakan sebagai dugaan level saat ini, sedangkan \(b_t\) menunjukkan besar tren per periode. :contentReferenceoaicite:3

Untuk observasi terakhir, yaitu Juni 2024:

\[ M'_t=281,67 \]

\[ M''_t=276,67 \]

sehingga:

\[ a_t=286,67 \]

dan

\[ b_t=5,00 \]

Artinya pada titik terakhir, DMA mengestimasi level sekitar 286,67 pengunjung dengan kecenderungan tren sekitar 5 pengunjung per bulan.

a_last <- tail(na.omit(a_t), 1)
b_last <- tail(na.omit(b_t), 1)

forecast_1 <- a_last + b_last * 1
forecast_2 <- a_last + b_last * 2

sma_last <- tail(na.omit(Mp), 1)

forecast_sma_1 <- sma_last
forecast_sma_2 <- sma_last

hasil_forecast <- data.frame(
  Periode = c("Juli 2024", "Agustus 2024"),
  DMA = c(forecast_1, forecast_2),
  SMA = c(forecast_sma_1, forecast_sma_2)
)

hasil_forecast$Selisih <- 
  hasil_forecast$DMA - hasil_forecast$SMA

hasil_forecast$DMA <- round(hasil_forecast$DMA, 2)
hasil_forecast$SMA <- round(hasil_forecast$SMA, 2)
hasil_forecast$Selisih <- round(hasil_forecast$Selisih, 2)

hasil_forecast
##        Periode    DMA    SMA Selisih
## 1    Juli 2024 292.78 281.67   11.11
## 2 Agustus 2024 298.33 281.67   16.67

Berdasarkan hasil peramalan, DMA menghasilkan ramalan jumlah pengunjung sebesar 291,67 orang untuk Juli 2024 dan 296,67 orang untuk Agustus 2024. Sementara itu ramalan menggunakan SMA sebesar 281,67 orang untuk kedua periode. Perbedaan terjadi karena DMA memperhitungkan komponen tren melalui \(b_t\), sedangkan SMA hanya menggunakan rata-rata observasi sebelumnya. Karena data pengunjung menunjukkan kecenderungan meningkat, DMA memberikan ramalan yang ikut meningkat sedangkan SMA menghasilkan ramalan yang relatif datar dan cenderung tertinggal.