INPUT DATA

# Data
head(data)
## # A tibble: 6 × 6
##   `Kota/Kabupaten`  Tanggal `Harga Beras (Rp/kg)` `Harga Cabai Merah (Rp/kg)`
##   <chr>             <chr>                   <dbl>                       <dbl>
## 1 Kabupaten Pacitan 2021-01                12248.                      28894.
## 2 Kabupaten Pacitan 2021-02                11883.                      28127.
## 3 Kabupaten Pacitan 2021-03                11765.                      34340.
## 4 Kabupaten Pacitan 2021-04                12121.                      14694.
## 5 Kabupaten Pacitan 2021-05                11494.                      32514.
## 6 Kabupaten Pacitan 2021-06                12733.                      28194.
## # ℹ 2 more variables: `Curah Hujan (mm/bulan)` <dbl>,
## #   `Tingkat Inflasi (%)` <dbl>
# Ubah format tanggal
data <- data %>%
  mutate(
    Tanggal = ym(Tanggal),
    Tahun = year(Tanggal),
    Bulan = month(Tanggal, label = TRUE, abbr = TRUE)
  )

# Pastikan nama kolom mudah dipakai
data <- data %>%
  rename(
    kota = `Kota/Kabupaten`,
    harga_beras = `Harga Beras (Rp/kg)`,
    harga_cabai = `Harga Cabai Merah (Rp/kg)`,
    curah_hujan = `Curah Hujan (mm/bulan)`,
    inflasi = `Tingkat Inflasi (%)`
  )

# Cek data kosong
colSums(is.na(data))
##        kota     Tanggal harga_beras harga_cabai curah_hujan     inflasi 
##           0           0           0           0           0           0 
##       Tahun       Bulan 
##           0           0

EKSPLORASI DATA

Harga beras biasanya lebih stabil karena standar deviasinya kecil.Harga cabai merah lebih fluktuatif karena standar deviasinya lebih besar.

statistik_kota <- data %>%
  group_by(kota) %>%
  summarise(
    rata2_beras = mean(harga_beras, na.rm = TRUE),
    sd_beras = sd(harga_beras, na.rm = TRUE),
    min_beras = min(harga_beras, na.rm = TRUE),
    max_beras = max(harga_beras, na.rm = TRUE),
    
    rata2_cabai = mean(harga_cabai, na.rm = TRUE),
    sd_cabai = sd(harga_cabai, na.rm = TRUE),
    min_cabai = min(harga_cabai, na.rm = TRUE),
    max_cabai = max(harga_cabai, na.rm = TRUE)
  ) %>%
  arrange(desc(rata2_cabai))

print(statistik_kota)
## # A tibble: 38 × 9
##    kota  rata2_beras sd_beras min_beras max_beras rata2_cabai sd_cabai min_cabai
##    <chr>       <dbl>    <dbl>     <dbl>     <dbl>       <dbl>    <dbl>     <dbl>
##  1 Kabu…      12062.     423.    10914.    12937.      32544.    7620.    18494.
##  2 Kabu…      11892.     509.    10750.    13160.      32339.    9670.    12777.
##  3 Kabu…      11973.     480.    10932.    13037.      32224.    7143.    18963.
##  4 Kabu…      12096.     523.    11172.    13141.      32001.    8795.    14935.
##  5 Kabu…      11882.     445.    10675.    12797.      31809.    7256.    19991.
##  6 Kota…      12122.     521.    10948.    13139.      31712.    9026.    13313.
##  7 Kabu…      12010.     505.    10923.    12998.      31660.    8013.    19072.
##  8 Kabu…      12041.     429.    11192.    13031.      31629.    7980.    15068.
##  9 Kabu…      12019.     473.    11143.    13030.      31372.    6760.    15930.
## 10 Kabu…      12153.     475.    11276.    13263.      31135.    9200.    10609.
## # ℹ 28 more rows
## # ℹ 1 more variable: max_cabai <dbl>

BOXPLOT HARGA CABAI MERAH

ggplot(data, aes(x = reorder(kota, harga_cabai, median), y = harga_cabai)) +
  geom_boxplot(outlier.color = "red", outlier.size = 2) +
  coord_flip() +
  labs(
    title = "Distribusi Harga Cabai Merah per Kota/Kabupaten",
    subtitle = "Provinsi Jawa Timur, Januari 2021 - Desember 2023",
    x = "Kota/Kabupaten",
    y = "Harga Cabai Merah (Rp/kg)"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold"),
    axis.text.y = element_text(size = 7)
  )

CEK OUTLIER DATA

Kota/kabupaten dengan jumlah outlier terbanyak dapat dianggap memiliki harga cabai merah yang cenderung ekstrem selama periode pengamatan.

outlier_cabai <- data %>%
  group_by(kota) %>%
  mutate(
    Q1 = quantile(harga_cabai, 0.25, na.rm = TRUE),
    Q3 = quantile(harga_cabai, 0.75, na.rm = TRUE),
    IQR_cabai = Q3 - Q1,
    batas_bawah = Q1 - 1.5 * IQR_cabai,
    batas_atas = Q3 + 1.5 * IQR_cabai,
    status_outlier = ifelse(
      harga_cabai < batas_bawah | harga_cabai > batas_atas,
      "Outlier",
      "Normal"
    )
  ) %>%
  ungroup()

jumlah_outlier <- outlier_cabai %>%
  filter(status_outlier == "Outlier") %>%
  group_by(kota) %>%
  summarise(jumlah_outlier = n()) %>%
  arrange(desc(jumlah_outlier))

print(jumlah_outlier)
## # A tibble: 13 × 2
##    kota                  jumlah_outlier
##    <chr>                          <int>
##  1 Kabupaten Pacitan                  4
##  2 Kabupaten Sumenep                  2
##  3 Kota Madiun                        2
##  4 Kota Probolinggo                   2
##  5 Kabupaten Bangkalan                1
##  6 Kabupaten Gresik                   1
##  7 Kabupaten Jombang                  1
##  8 Kabupaten Magetan                  1
##  9 Kabupaten Pamekasan                1
## 10 Kabupaten Pasuruan                 1
## 11 Kabupaten Ponorogo                 1
## 12 Kabupaten Tulungagung              1
## 13 Kota Blitar                        1

VISUALISASI TIME SERIES

# Filter Kota Pilihan
kota_pilihan <- c("Kota Surabaya", "Kota Malang","Kota Blitar")

data_ts <- data %>%
  filter(kota %in% kota_pilihan)

# Time series harga beras
ggplot(data_ts, aes(x = Tanggal, y = harga_beras, color = kota)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  labs(
    title = "Time Series Harga Beras",
    subtitle = "Beberapa Kota di Jawa Timur, 2021-2023",
    x = "Tanggal",
    y = "Harga Beras (Rp/kg)",
    color = "Wilayah"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(plot.title = element_text(face = "bold"))

# Time series harga cabai merah
ggplot(data_ts, aes(x = Tanggal, y = harga_cabai, color = kota)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  labs(
    title = "Time Series Harga Cabai Merah",
    subtitle = "Beberapa Kota di Jawa Timur, 2021-2023",
    x = "Tanggal",
    y = "Harga Cabai Merah (Rp/kg)",
    color = "Wilayah"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(plot.title = element_text(face = "bold"))

FLUKTUASI HARGA

Fluktuasi tajam harga cabai merah dapat disebabkan oleh perubahan pasokan,cuaca ekstrem, gagal panen, gangguan distribusi, atau peningkatan permintaan pada periode tertentu.

fluktuasi <- data_ts %>%
  arrange(kota, Tanggal) %>%
  group_by(kota) %>%
  mutate(
    perubahan_beras = harga_beras - lag(harga_beras),
    perubahan_cabai = harga_cabai - lag(harga_cabai)
  ) %>%
  ungroup()

# Fluktuasi tajam harga beras
fluktuasi_beras_tajam <- fluktuasi %>%
  group_by(kota) %>%
  filter(abs(perubahan_beras) == max(abs(perubahan_beras), na.rm = TRUE)) %>%
  select(kota, Tanggal, harga_beras, perubahan_beras)

print(fluktuasi_beras_tajam)
## # A tibble: 3 × 4
## # Groups:   kota [3]
##   kota          Tanggal    harga_beras perubahan_beras
##   <chr>         <date>           <dbl>           <dbl>
## 1 Kota Blitar   2021-06-01      12471.           1301.
## 2 Kota Malang   2023-05-01      11412.           -993.
## 3 Kota Surabaya 2021-07-01      11487.          -1704.
# Fluktuasi tajam harga cabai
fluktuasi_cabai_tajam <- fluktuasi %>%
  group_by(kota) %>%
  filter(abs(perubahan_cabai) == max(abs(perubahan_cabai), na.rm = TRUE)) %>%
  select(kota, Tanggal, harga_cabai, perubahan_cabai)

print(fluktuasi_cabai_tajam)
## # A tibble: 3 × 4
## # Groups:   kota [3]
##   kota          Tanggal    harga_cabai perubahan_cabai
##   <chr>         <date>           <dbl>           <dbl>
## 1 Kota Blitar   2022-12-01      10016.         -26994.
## 2 Kota Malang   2023-10-01      40330.          27703.
## 3 Kota Surabaya 2021-02-01      43849.          29490.
# Visualisasi beras dengan titik fluktuasi tajam
ggplot(fluktuasi, aes(x = Tanggal, y = harga_beras, color = kota)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  geom_point(
    data = fluktuasi_beras_tajam,
    aes(x = Tanggal, y = harga_beras),
    color = "black",
    size = 4
  ) +
  labs(
    title = "Fluktuasi Tajam Harga Beras",
    subtitle = "Titik hitam menunjukkan perubahan harga paling tajam",
    x = "Tanggal",
    y = "Harga Beras (Rp/kg)",
    color = "Wilayah"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(plot.title = element_text(face = "bold"))

# Visualisasi cabai dengan titik fluktuasi tajam
ggplot(fluktuasi, aes(x = Tanggal, y = harga_cabai, color = kota)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  geom_point(
    data = fluktuasi_cabai_tajam,
    aes(x = Tanggal, y = harga_cabai),
    color = "black",
    size = 4
  ) +
  labs(
    title = "Fluktuasi Tajam Harga Cabai Merah",
    subtitle = "Titik hitam menunjukkan perubahan harga paling tajam",
    x = "Tanggal",
    y = "Harga Cabai Merah (Rp/kg)",
    color = "Wilayah"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(plot.title = element_text(face = "bold"))

ANALISIS POLA MUSIMAN HARGA

Jika terdapat bulan tertentu dengan rata-rata harga lebih tinggi,maka dapat dikatakan terdapat indikasi pola musiman. Biasanya harga cabai merah lebih musiman dibanding harga beras.

pola_musiman <- data %>%
  group_by(Bulan) %>%
  summarise(
    rata2_beras = mean(harga_beras, na.rm = TRUE),
    rata2_cabai = mean(harga_cabai, na.rm = TRUE)
  )

print(pola_musiman)
## # A tibble: 12 × 3
##    Bulan rata2_beras rata2_cabai
##    <ord>       <dbl>       <dbl>
##  1 Jan        12027.      28815.
##  2 Feb        12028.      31699.
##  3 Mar        12042.      29808.
##  4 Apr        12035.      30515.
##  5 May        11990.      31197.
##  6 Jun        12036.      28704.
##  7 Jul        11970.      30173.
##  8 Aug        12015.      29490.
##  9 Sep        12003.      29479.
## 10 Oct        12052.      29750.
## 11 Nov        11978.      30455.
## 12 Dec        11994.      29757.
# Ubah data ke format long agar mudah diplot
pola_musiman_long <- pola_musiman %>%
  pivot_longer(
    cols = c(rata2_beras, rata2_cabai),
    names_to = "komoditas",
    values_to = "harga"
  ) %>%
  mutate(
    komoditas = case_when(
      komoditas == "rata2_beras" ~ "Beras",
      komoditas == "rata2_cabai" ~ "Cabai Merah"
    ),
    label_harga = paste0(comma(round(harga, 0))),
    
    # Supaya label tidak menumpuk dengan garis
    posisi_label = case_when(
      komoditas == "Beras" ~ harga - 900,
      komoditas == "Cabai Merah" ~ harga + 900
    )
  )

# Plot pola musiman dengan label harga
ggplot(pola_musiman_long, aes(x = Bulan, y = harga, group = komoditas, color = komoditas)) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 3) +
  geom_label(
    aes(y = posisi_label, label = label_harga),
    size = 3,
    show.legend = FALSE,
    label.size = 0.2
  ) +
  labs(
    title = "Pola Musiman Harga Beras dan Cabai Merah",
    subtitle = "Rata-rata bulanan seluruh Kota/Kabupaten di Jawa Timur, 2021-2023",
    x = "Bulan",
    y = "Harga Rata-rata (Rupiah)",
    color = "Komoditas"
  ) +
  scale_y_continuous(labels = comma) +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold"),
    legend.position = "top"
  )
## Warning: The `label.size` argument of `geom_label()` is deprecated as of ggplot2 3.5.0.
## ℹ Please use the `linewidth` argument instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.