Eksplorasi Data Lingkungan: Volume Sampah Sungai di DKI Jakarta
1 Pendahuluan
Sampah sungai merupakan salah satu permasalahan lingkungan yang berkaitan dengan kualitas ekosistem perairan, sistem drainase, serta pengelolaan sampah perkotaan. Volume sampah yang ditemukan pada badan sungai dapat berubah dari waktu ke waktu dan berbeda antarwilayah.
Data yang digunakan merupakan data lingkungan aktual dari Portal Data Terbuka Pemerintah Provinsi DKI Jakarta.
Data utama yang digunakan adalah dataset Rata-Rata Volume Sampah Sungai di Provinsi DKI Jakarta Menurut Kota Administrasi.
Analisis meliputi statistik deskriptif, visualisasi, deteksi outlier, autokorelasi temporal menggunakan ACF, serta analisis spasial menggunakan Moran’s I dan Local Moran’s I.
2 Tujuan Analisis
- Mendeskripsikan karakteristik volume sampah sungai di DKI Jakarta.
- Membandingkan volume sampah antarwilayah.
- Mengidentifikasi outlier menggunakan metode IQR.
- Mengamati pola perubahan volume sampah secara temporal.
- Menguji autokorelasi temporal menggunakan ACF.
- Menguji pola spasial menggunakan Moran’s I.
- Memvisualisasikan distribusi volume sampah pada tingkat kecamatan.
3 Persiapan Data
3.1 Direktori Kerja
## [1] "C:/Users/sambe/Downloads/TUGAS 1 STAT LINGKUNGAN"
3.2 Import Data
3.3 Cleaning Data
data <- data_raw |>
clean_names() |>
mutate(
periode_data = as.character(periode_data),
tanggal = ymd(paste0(periode_data, "01")),
wilayah = str_squish(wilayah),
kecamatan = str_squish(kecamatan),
volume_sampah = as.numeric(volume_sampah),
total_sampah_residu = as.numeric(total_sampah_residu),
rata_rata = as.numeric(rata_rata)
) |>
filter(!is.na(rata_rata))3.4 Struktur Data
## Rows: 1,302
## Columns: 7
## $ periode_data <chr> "202401", "202401", "202401", "202401", "202401", …
## $ wilayah <chr> "KOTA ADM. JAKARTA PUSAT", "KOTA ADM. JAKARTA PUSA…
## $ kecamatan <chr> "KEMAYORAN", "CEMPAKA PUTIH", "JOHAR BARU", "SENEN…
## $ volume_sampah <dbl> 999.04, 363.91, 715.29, 500.13, 693.33, 841.22, 68…
## $ total_sampah_residu <dbl> 997.0, 363.0, 714.0, 498.0, 692.0, 837.0, 682.0, 7…
## $ rata_rata <dbl> 32.16, 11.71, 23.03, 16.06, 22.32, 27.00, 22.00, 2…
## $ tanggal <date> 2024-01-01, 2024-01-01, 2024-01-01, 2024-01-01, 2…
data |>
summarise(
jumlah_observasi = n(),
jumlah_kecamatan = n_distinct(kecamatan),
jumlah_kota = n_distinct(wilayah),
periode_awal = min(tanggal, na.rm = TRUE),
periode_akhir = max(tanggal, na.rm = TRUE)
) |>
kable(caption = "Ringkasan Struktur Data") |>
kable_styling(full_width = FALSE)| jumlah_observasi | jumlah_kecamatan | jumlah_kota | periode_awal | periode_akhir |
|---|---|---|---|---|
| 1302 | 46 | 5 | 2024-01-01 | 2026-07-01 |
3.5 Distribusi Observasi Berdasarkan Kota
data |>
count(wilayah, sort = TRUE) |>
kable(
col.names = c("Kota Administrasi", "Jumlah Observasi"),
caption = "Jumlah Observasi Berdasarkan Kota Administrasi"
) |>
kable_styling(full_width = FALSE)| Kota Administrasi | Jumlah Observasi |
|---|---|
| KOTA ADM. JAKARTA SELATAN | 310 |
| KOTA ADM. JAKARTA TIMUR | 310 |
| KOTA ADM. JAKARTA BARAT | 248 |
| KOTA ADM. JAKARTA PUSAT | 248 |
| KOTA ADM. JAKARTA UTARA | 186 |
4 Statistik Deskriptif
Statistik deskriptif digunakan untuk mengetahui kecenderungan pusat dan tingkat penyebaran volume sampah sungai. Ukuran yang digunakan meliputi mean, median, standar deviasi, varians, minimum, kuartil, IQR, dan maksimum.
4.1 Statistik Keseluruhan
statistik_deskriptif <- data |>
summarise(
N = n(),
Mean = mean(rata_rata, na.rm = TRUE),
Median = median(rata_rata, na.rm = TRUE),
SD = sd(rata_rata, na.rm = TRUE),
Varians = var(rata_rata, na.rm = TRUE),
Minimum = min(rata_rata, na.rm = TRUE),
Q1 = quantile(rata_rata, 0.25, na.rm = TRUE),
Q3 = quantile(rata_rata, 0.75, na.rm = TRUE),
IQR = IQR(rata_rata, na.rm = TRUE),
Maksimum = max(rata_rata, na.rm = TRUE)
)
statistik_deskriptif |>
mutate(across(where(is.numeric), ~ round(.x, 2))) |>
kable(caption = "Statistik Deskriptif Volume Sampah Sungai") |>
kable_styling(full_width = FALSE)| N | Mean | Median | SD | Varians | Minimum | Q1 | Q3 | IQR | Maksimum |
|---|---|---|---|---|---|---|---|---|---|
| 1302 | 30.38 | 20.71 | 35.82 | 1282.83 | 0.47 | 15.6 | 29.55 | 13.95 | 316.87 |
4.2 Statistik Berdasarkan Kota
statistik_kota <- data |>
group_by(wilayah) |>
summarise(
N = n(),
Mean = mean(rata_rata, na.rm = TRUE),
Median = median(rata_rata, na.rm = TRUE),
SD = sd(rata_rata, na.rm = TRUE),
Minimum = min(rata_rata, na.rm = TRUE),
Q1 = quantile(rata_rata, 0.25, na.rm = TRUE),
Q3 = quantile(rata_rata, 0.75, na.rm = TRUE),
Maksimum = max(rata_rata, na.rm = TRUE),
.groups = "drop"
) |>
mutate(across(where(is.numeric), ~ round(.x, 2)))
statistik_kota |>
kable(
col.names = c("Kota Administrasi", "N", "Mean", "Median", "SD",
"Minimum", "Q1", "Q3", "Maksimum"),
caption = "Statistik Deskriptif Berdasarkan Kota Administrasi"
) |>
kable_styling(full_width = FALSE)| Kota Administrasi | N | Mean | Median | SD | Minimum | Q1 | Q3 | Maksimum |
|---|---|---|---|---|---|---|---|---|
| KOTA ADM. JAKARTA BARAT | 248 | 38.07 | 30.45 | 33.21 | 10.63 | 24.13 | 42.14 | 233.86 |
| KOTA ADM. JAKARTA PUSAT | 248 | 25.35 | 19.67 | 32.51 | 1.01 | 15.38 | 23.41 | 208.11 |
| KOTA ADM. JAKARTA SELATAN | 310 | 27.84 | 17.11 | 40.96 | 0.47 | 13.27 | 20.59 | 316.87 |
| KOTA ADM. JAKARTA TIMUR | 310 | 27.50 | 18.31 | 34.02 | 0.64 | 13.43 | 27.20 | 242.89 |
| KOTA ADM. JAKARTA UTARA | 186 | 35.90 | 24.26 | 35.12 | 0.89 | 19.59 | 40.09 | 239.00 |
5 Visualisasi
5.1 Histogram
ggplot(data, aes(x = rata_rata)) +
geom_histogram(bins = 40, fill = "steelblue", color = "white") +
geom_vline(
aes(xintercept = mean(rata_rata, na.rm = TRUE)),
linetype = "dashed", linewidth = 1
) +
labs(
title = "Distribusi Rata-Rata Volume Sampah Sungai",
subtitle = "DKI Jakarta, 2024–2026",
x = "Rata-rata Volume Sampah",
y = "Frekuensi"
) +
theme_minimal()5.2 Boxplot
ggplot(data, aes(y = rata_rata)) +
geom_boxplot(fill = "lightblue", outlier.alpha = 0.5) +
labs(
title = "Boxplot Rata-Rata Volume Sampah Sungai",
x = NULL,
y = "Rata-rata Volume Sampah"
) +
theme_minimal()5.3 Boxplot Berdasarkan Kota
ggplot(
data,
aes(
x = reorder(wilayah, rata_rata, FUN = median),
y = rata_rata
)
) +
geom_boxplot(aes(group = wilayah), fill = "lightblue", outlier.alpha = 0.4) +
labs(
title = "Distribusi Volume Sampah Berdasarkan Kota Administrasi",
x = "Kota Administrasi",
y = "Rata-rata Volume Sampah"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 35, hjust = 1))6 Analisis Temporal
6.1 Agregasi Bulanan
6.2 Time Series
ggplot(data_bulanan, aes(x = tanggal, y = rata_rata_volume)) +
geom_line(linewidth = 1) +
geom_point(size = 1.8) +
labs(
title = "Perubahan Rata-Rata Volume Sampah Sungai",
x = "Periode",
y = "Rata-rata Volume Sampah"
) +
scale_x_date(date_breaks = "3 months", date_labels = "%b\n%Y") +
theme_minimal()6.3 Tren Berdasarkan Kota
data_kota_bulanan <- data |>
group_by(wilayah, tanggal) |>
summarise(
rata_rata_volume = mean(rata_rata, na.rm = TRUE),
.groups = "drop"
)
ggplot(
data_kota_bulanan,
aes(x = tanggal, y = rata_rata_volume, group = wilayah)
) +
geom_line(linewidth = 0.9) +
geom_point(size = 1.3) +
facet_wrap(~ wilayah, scales = "free_y") +
labs(
title = "Pola Temporal Volume Sampah Berdasarkan Kota Administrasi",
x = "Periode",
y = "Rata-rata Volume Sampah"
) +
scale_x_date(date_breaks = "6 months", date_labels = "%b\n%Y") +
theme_minimal()7 Analisis Outlier
7.1 Batas IQR
Outlier ditentukan menggunakan metode Interquartile Range (IQR).
Batas bawah:
\[ Q1 - 1.5(IQR) \]
Batas atas:
\[ Q3 + 1.5(IQR) \]
Q1 <- quantile(data$rata_rata, 0.25, na.rm = TRUE)
Q3 <- quantile(data$rata_rata, 0.75, na.rm = TRUE)
IQR_value <- IQR(data$rata_rata, na.rm = TRUE)
batas_bawah <- Q1 - 1.5 * IQR_value
batas_atas <- Q3 + 1.5 * IQR_value
tibble(
Q1 = Q1,
Q3 = Q3,
IQR = IQR_value,
Batas_Bawah = batas_bawah,
Batas_Atas = batas_atas
) |>
mutate(across(where(is.numeric), ~ round(.x, 2))) |>
kable(caption = "Batas Outlier Berdasarkan Metode IQR") |>
kable_styling(full_width = FALSE)| Q1 | Q3 | IQR | Batas_Bawah | Batas_Atas |
|---|---|---|---|---|
| 15.6 | 29.55 | 13.95 | -5.32 | 50.46 |
7.2 Identifikasi Outlier
data_outlier <- data |>
mutate(
status_outlier = case_when(
rata_rata < batas_bawah ~ "Outlier bawah",
rata_rata > batas_atas ~ "Outlier atas",
TRUE ~ "Normal"
)
)
data_outlier |>
count(status_outlier) |>
kable(
col.names = c("Status", "Jumlah"),
caption = "Jumlah Observasi Berdasarkan Status Outlier"
) |>
kable_styling(full_width = FALSE)| Status | Jumlah |
|---|---|
| Normal | 1170 |
| Outlier atas | 132 |
7.3 Detail Outlier
data_outlier |>
filter(status_outlier != "Normal") |>
select(periode_data, tanggal, wilayah, kecamatan, rata_rata, status_outlier) |>
arrange(desc(rata_rata)) |>
head(20) |>
mutate(rata_rata = round(rata_rata, 2)) |>
kable(
col.names = c("Periode", "Tanggal", "Kota Administrasi",
"Kecamatan", "Rata-rata", "Status"),
caption = "20 Observasi Outlier dengan Nilai Tertinggi"
) |>
kable_styling(
full_width = FALSE,
bootstrap_options = c("striped", "hover")
)| Periode | Tanggal | Kota Administrasi | Kecamatan | Rata-rata | Status |
|---|---|---|---|---|---|
| 202511 | 2025-11-01 | KOTA ADM. JAKARTA SELATAN | JAGAKARSA | 316.87 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA TIMUR | CAKUNG | 242.89 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA UTARA | PENJARINGAN | 239.00 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA BARAT | CENGKARENG | 233.86 | Outlier atas |
| 202402 | 2024-02-01 | KOTA ADM. JAKARTA SELATAN | JAGAKARSA | 220.00 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA BARAT | KEMBANGAN | 219.14 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA UTARA | TANJUNG PRIOK | 216.89 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA SELATAN | JAGAKARSA | 214.75 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA TIMUR | KRAMATJATI | 209.32 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA PUSAT | KEMAYORAN | 208.11 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA PUSAT | TANAH ABANG | 207.29 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA BARAT | GROGOL PETAMBURAN | 206.04 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA PUSAT | JOHAR BARU | 204.96 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA BARAT | KEBON JERUK | 204.75 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA TIMUR | PASAR REBO | 204.75 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA BARAT | KALIDERES | 203.82 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA UTARA | PADEMANGAN | 203.25 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA UTARA | CILINCING | 199.25 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA BARAT | TAMBORA | 198.34 | Outlier atas |
| 202602 | 2026-02-01 | KOTA ADM. JAKARTA PUSAT | SENEN | 197.96 | Outlier atas |
7.4 Visualisasi Outlier
ggplot(data_outlier, aes(x = tanggal, y = rata_rata, color = status_outlier)) +
geom_point(alpha = 0.65) +
geom_hline(yintercept = batas_atas, linetype = "dashed", linewidth = 0.8) +
labs(
title = "Identifikasi Outlier Volume Sampah Sungai",
x = "Periode",
y = "Rata-rata Volume Sampah",
color = "Status"
) +
theme_minimal()Outlier tidak langsung dianggap sebagai kesalahan data. Nilai ekstrem dapat merepresentasikan kondisi lingkungan yang berbeda pada waktu atau lokasi tertentu.
8 Autokorelasi Temporal
Autokorelasi temporal digunakan untuk mengetahui apakah nilai pada suatu periode memiliki hubungan dengan periode sebelumnya.
8.1 ACF
Jika spike ACF melewati batas signifikansi, terdapat indikasi hubungan temporal pada lag tersebut.
8.2 Nilai ACF
acf_result <- acf(
data_bulanan$rata_rata_volume,
plot = FALSE
)
tibble(
lag = as.numeric(acf_result$lag),
autocorrelation = as.numeric(acf_result$acf)
) |>
filter(lag > 0) |>
head(12) |>
mutate(
lag = round(lag, 0),
autocorrelation = round(autocorrelation, 3)
) |>
kable(caption = "Nilai Autokorelasi Temporal pada Beberapa Lag") |>
kable_styling(full_width = FALSE)| lag | autocorrelation |
|---|---|
| 1 | -0.066 |
| 2 | -0.040 |
| 3 | -0.050 |
| 4 | -0.083 |
| 5 | -0.067 |
| 6 | -0.007 |
| 7 | -0.025 |
| 8 | -0.004 |
| 9 | -0.015 |
| 10 | -0.012 |
| 11 | -0.013 |
| 12 | -0.018 |
9 Analisis Geospasial
Data spasial yang digunakan adalah batas administrasi kecamatan. Unit spasial dibuat sama dengan unit pada data statistik.
9.1 Folder Shapefile
folder_kota <- c(
"JAKARTA PUSAT",
"JAKARTA SELATAN",
"JAKARTA BARAT",
"JAKARTA TIMUR",
"JAKARTA UTARA"
)
file_shp <- file.path(
folder_kota,
"ADMINISTRASIKECAMATAN_AR_25K.shp"
)
tibble(
kota = folder_kota,
file_shp = file_shp,
tersedia = file.exists(file_shp)
) |>
kable(caption = "Daftar Shapefile Batas Kecamatan") |>
kable_styling(full_width = FALSE)| kota | file_shp | tersedia |
|---|---|---|
| JAKARTA PUSAT | JAKARTA PUSAT/ADMINISTRASIKECAMATAN_AR_25K.shp | TRUE |
| JAKARTA SELATAN | JAKARTA SELATAN/ADMINISTRASIKECAMATAN_AR_25K.shp | TRUE |
| JAKARTA BARAT | JAKARTA BARAT/ADMINISTRASIKECAMATAN_AR_25K.shp | TRUE |
| JAKARTA TIMUR | JAKARTA TIMUR/ADMINISTRASIKECAMATAN_AR_25K.shp | TRUE |
| JAKARTA UTARA | JAKARTA UTARA/ADMINISTRASIKECAMATAN_AR_25K.shp | TRUE |
9.2 Membaca Seluruh Shapefile
9.3 Field Shapefile
tibble(
nomor = seq_along(names(shp_jakarta)),
field = names(shp_jakarta)
) |>
kable(caption = "Field pada Shapefile Administrasi Kecamatan") |>
kable_styling(full_width = FALSE)| nomor | field |
|---|---|
| 1 | KDPPUM |
| 2 | NAMOBJ |
| 3 | REMARK |
| 4 | KDPBPS |
| 5 | FCODE |
| 6 | LUASWH |
| 7 | UUPP |
| 8 | SRS_ID |
| 9 | LCODE |
| 10 | METADATA |
| 11 | KDEBPS |
| 12 | KDEPUM |
| 13 | KDCBPS |
| 14 | KDCPUM |
| 15 | KDBBPS |
| 16 | KDBPUM |
| 17 | WADMKD |
| 18 | WIADKD |
| 19 | WADMKC |
| 20 | WIADKC |
| 21 | WADMKK |
| 22 | WIADKK |
| 23 | WADMPR |
| 24 | WIADPR |
| 25 | TIPADM |
| 26 | SHAPE_Leng |
| 27 | SHAPE_Area |
| 28 | kota_shp |
| 29 | geometry |
9.4 Deteksi Field Nama Kecamatan
kecamatan_data <- data |>
mutate(kecamatan_clean = str_to_upper(str_squish(kecamatan))) |>
distinct(kecamatan_clean) |>
pull(kecamatan_clean)
candidate_fields <- names(shp_jakarta)[
!names(shp_jakarta) %in% c("geometry", "kota_shp")
]
field_score <- map_dfr(
candidate_fields,
function(f) {
nilai_shp <- shp_jakarta[[f]]
if (!is.character(nilai_shp) && !is.factor(nilai_shp)) {
return(tibble(field = f, matched = 0, total_unique = 0))
}
nilai_shp <- str_to_upper(str_squish(as.character(nilai_shp)))
tibble(
field = f,
matched = sum(nilai_shp %in% kecamatan_data, na.rm = TRUE),
total_unique = n_distinct(nilai_shp)
)
}
) |>
arrange(desc(matched), desc(total_unique))
field_score |>
head(15) |>
kable(
caption = "Skor Kecocokan Field Shapefile dengan Nama Kecamatan"
) |>
kable_styling(full_width = FALSE)| field | matched | total_unique |
|---|---|---|
| NAMOBJ | 41 | 42 |
| WADMKK | 0 | 5 |
| KDPPUM | 0 | 1 |
| REMARK | 0 | 1 |
| KDPBPS | 0 | 1 |
| FCODE | 0 | 1 |
| UUPP | 0 | 1 |
| SRS_ID | 0 | 1 |
| LCODE | 0 | 1 |
| METADATA | 0 | 1 |
| KDEBPS | 0 | 1 |
| KDEPUM | 0 | 1 |
| KDCBPS | 0 | 1 |
| KDCPUM | 0 | 1 |
| KDBBPS | 0 | 1 |
field_kecamatan <- field_score |>
filter(matched == max(matched, na.rm = TRUE)) |>
slice(1) |>
pull(field)
field_kecamatan## [1] "NAMOBJ"
9.5 Standardisasi Nama Kecamatan
9.6 Pemeriksaan Kecocokan
shp_jakarta |>
st_drop_geometry() |>
distinct(kecamatan, kota_shp) |>
mutate(cocok = kecamatan %in% data_spasial$kecamatan) |>
count(cocok) |>
kable(
col.names = c("Nama Kecamatan Cocok", "Jumlah"),
caption = "Pemeriksaan Kecocokan Nama Kecamatan"
) |>
kable_styling(full_width = FALSE)| Nama Kecamatan Cocok | Jumlah |
|---|---|
| FALSE | 1 |
| TRUE | 41 |
10 Peta Administrasi
ggplot(shp_jakarta) +
geom_sf(fill = "grey95", color = "grey40", linewidth = 0.25) +
labs(
title = "Peta Administrasi Kecamatan DKI Jakarta",
subtitle = "Batas wilayah berdasarkan shapefile administrasi kecamatan",
x = NULL, y = NULL
) +
theme_minimal()11 Penggabungan Data Statistik dan Spasial
Data statistik diringkas pada tingkat kecamatan selama seluruh periode pengamatan.
data_spasial_kecamatan <- data_spasial |>
group_by(wilayah, kecamatan) |>
summarise(
rata_rata = mean(rata_rata, na.rm = TRUE),
median = median(rata_rata, na.rm = TRUE),
sd = sd(rata_rata, na.rm = TRUE),
minimum = min(rata_rata, na.rm = TRUE),
maksimum = max(rata_rata, na.rm = TRUE),
jumlah_observasi = n(),
.groups = "drop"
) |>
mutate(
kota_shp = case_when(
wilayah == "KOTA ADM. JAKARTA PUSAT" ~ "JAKARTA PUSAT",
wilayah == "KOTA ADM. JAKARTA SELATAN" ~ "JAKARTA SELATAN",
wilayah == "KOTA ADM. JAKARTA BARAT" ~ "JAKARTA BARAT",
wilayah == "KOTA ADM. JAKARTA TIMUR" ~ "JAKARTA TIMUR",
wilayah == "KOTA ADM. JAKARTA UTARA" ~ "JAKARTA UTARA",
TRUE ~ NA_character_
)
)
jakarta_map <- shp_jakarta |>
left_join(
data_spasial_kecamatan,
by = c("kecamatan", "kota_shp")
)11.1 Pemeriksaan Join
jakarta_map |>
st_drop_geometry() |>
summarise(
total_polygon = n(),
polygon_dengan_data = sum(!is.na(rata_rata)),
polygon_tanpa_data = sum(is.na(rata_rata))
) |>
kable(caption = "Pemeriksaan Penggabungan Data Statistik dan Spasial") |>
kable_styling(full_width = FALSE)| total_polygon | polygon_dengan_data | polygon_tanpa_data |
|---|---|---|
| 42 | 41 | 1 |
12 Peta Tematik
12.1 Rata-Rata Volume Seluruh Periode
ggplot(
jakarta_map |> filter(!is.na(rata_rata)),
aes(fill = rata_rata)
) +
geom_sf(color = "white", linewidth = 0.25) +
scale_fill_viridis_c(
option = "C",
name = "Rata-rata\nvolume"
) +
facet_wrap(~ kota_shp) +
labs(
title = "Distribusi Spasial Rata-Rata Volume Sampah Sungai",
subtitle = "Rata-rata seluruh periode pada tingkat kecamatan",
x = NULL, y = NULL
) +
theme_minimal() +
theme(
axis.text = element_blank(),
panel.grid = element_blank(),
strip.text = element_text(face = "bold")
)Peta menunjukkan variasi volume sampah antar kecamatan. Kecamatan dengan nilai rata-rata lebih tinggi menunjukkan volume sampah yang relatif lebih besar selama periode pengamatan.
12.2 Ranking Kecamatan
data_spasial_kecamatan |>
arrange(desc(rata_rata)) |>
mutate(peringkat = row_number()) |>
select(peringkat, wilayah, kecamatan, rata_rata, median, maksimum) |>
head(15) |>
mutate(across(where(is.numeric), ~ round(.x, 2))) |>
kable(
col.names = c("Peringkat", "Kota Administrasi", "Kecamatan",
"Mean", "Median", "Maksimum"),
caption = "15 Kecamatan dengan Rata-Rata Volume Sampah Tertinggi"
) |>
kable_styling(
full_width = FALSE,
bootstrap_options = c("striped", "hover")
)| Peringkat | Kota Administrasi | Kecamatan | Mean | Median | Maksimum |
|---|---|---|---|---|---|
| 1 | KOTA ADM. JAKARTA SELATAN | JAGAKARSA | 83.37 | 83.37 | 83.37 |
| 2 | KOTA ADM. JAKARTA UTARA | PENJARINGAN | 63.20 | 63.20 | 63.20 |
| 3 | KOTA ADM. JAKARTA TIMUR | CAKUNG | 58.67 | 58.67 | 58.67 |
| 4 | KOTA ADM. JAKARTA BARAT | CENGKARENG | 57.86 | 57.86 | 57.86 |
| 5 | KOTA ADM. JAKARTA BARAT | KEMBANGAN | 46.52 | 46.52 | 46.52 |
| 6 | KOTA ADM. JAKARTA UTARA | TANJUNG PRIOK | 44.30 | 44.30 | 44.30 |
| 7 | KOTA ADM. JAKARTA BARAT | KEBON JERUK | 42.56 | 42.56 | 42.56 |
| 8 | KOTA ADM. JAKARTA TIMUR | KRAMATJATI | 39.21 | 39.21 | 39.21 |
| 9 | KOTA ADM. JAKARTA BARAT | GROGOL PETAMBURAN | 34.71 | 34.71 | 34.71 |
| 10 | KOTA ADM. JAKARTA BARAT | KALIDERES | 34.62 | 34.62 | 34.62 |
| 11 | KOTA ADM. JAKARTA BARAT | TAMBORA | 34.44 | 34.44 | 34.44 |
| 12 | KOTA ADM. JAKARTA PUSAT | KEMAYORAN | 33.83 | 33.83 | 33.83 |
| 13 | KOTA ADM. JAKARTA TIMUR | PULOGADUNG | 33.14 | 33.14 | 33.14 |
| 14 | KOTA ADM. JAKARTA BARAT | PAL MERAH | 31.94 | 31.94 | 31.94 |
| 15 | KOTA ADM. JAKARTA UTARA | CILINCING | 31.73 | 31.73 | 31.73 |
13 Peta Periode Terakhir
periode_terakhir <- max(data$tanggal, na.rm = TRUE)
data_latest <- data |>
filter(tanggal == periode_terakhir) |>
group_by(wilayah, kecamatan) |>
summarise(
rata_rata = mean(rata_rata, na.rm = TRUE),
.groups = "drop"
) |>
mutate(
kota_shp = case_when(
wilayah == "KOTA ADM. JAKARTA PUSAT" ~ "JAKARTA PUSAT",
wilayah == "KOTA ADM. JAKARTA SELATAN" ~ "JAKARTA SELATAN",
wilayah == "KOTA ADM. JAKARTA BARAT" ~ "JAKARTA BARAT",
wilayah == "KOTA ADM. JAKARTA TIMUR" ~ "JAKARTA TIMUR",
wilayah == "KOTA ADM. JAKARTA UTARA" ~ "JAKARTA UTARA",
TRUE ~ NA_character_
)
)
map_latest <- shp_jakarta |>
left_join(data_latest, by = c("kecamatan", "kota_shp"))ggplot(
map_latest |> filter(!is.na(rata_rata)),
aes(fill = rata_rata)
) +
geom_sf(color = "white", linewidth = 0.25) +
scale_fill_viridis_c(option = "C", name = "Volume") +
facet_wrap(~ kota_shp) +
labs(
title = "Peta Volume Sampah Sungai pada Periode Terakhir",
subtitle = format(periode_terakhir, "%B %Y"),
x = NULL, y = NULL
) +
theme_minimal() +
theme(
axis.text = element_blank(),
panel.grid = element_blank(),
strip.text = element_text(face = "bold")
)14 Peta Frekuensi Outlier
outlier_frequency <- data_outlier |>
group_by(wilayah, kecamatan) |>
summarise(
jumlah_outlier = sum(status_outlier != "Normal", na.rm = TRUE),
.groups = "drop"
) |>
mutate(
kota_shp = case_when(
wilayah == "KOTA ADM. JAKARTA PUSAT" ~ "JAKARTA PUSAT",
wilayah == "KOTA ADM. JAKARTA SELATAN" ~ "JAKARTA SELATAN",
wilayah == "KOTA ADM. JAKARTA BARAT" ~ "JAKARTA BARAT",
wilayah == "KOTA ADM. JAKARTA TIMUR" ~ "JAKARTA TIMUR",
wilayah == "KOTA ADM. JAKARTA UTARA" ~ "JAKARTA UTARA",
TRUE ~ NA_character_
)
)
map_outlier <- shp_jakarta |>
left_join(outlier_frequency, by = c("kecamatan", "kota_shp"))ggplot(
map_outlier |> filter(!is.na(jumlah_outlier)),
aes(fill = jumlah_outlier)
) +
geom_sf(color = "white", linewidth = 0.25) +
scale_fill_viridis_c(option = "B", name = "Jumlah\noutlier") +
facet_wrap(~ kota_shp) +
labs(
title = "Distribusi Spasial Frekuensi Outlier",
subtitle = "Jumlah observasi outlier pada setiap kecamatan",
x = NULL, y = NULL
) +
theme_minimal() +
theme(
axis.text = element_blank(),
panel.grid = element_blank(),
strip.text = element_text(face = "bold")
)15 Global Moran’s I
Moran’s I digunakan untuk mengetahui apakah kecamatan yang berdekatan memiliki nilai volume sampah yang cenderung serupa.
15.1 Menyiapkan Unit Spasial
15.2 Spatial Neighbors
Queen contiguity digunakan untuk menentukan hubungan antarwilayah. Dua kecamatan dianggap bertetangga apabila memiliki bagian batas atau titik yang bersinggungan.
15.3 Jumlah Tetangga
tibble(
kecamatan = moran_map$kecamatan,
jumlah_tetangga = card(nb_jakarta)
) |>
arrange(desc(jumlah_tetangga)) |>
kable(caption = "Jumlah Tetangga Setiap Kecamatan") |>
kable_styling(full_width = FALSE)| kecamatan | jumlah_tetangga |
|---|---|
| GAMBIR | 8 |
| KEMAYORAN | 8 |
| KRAMATJATI | 8 |
| SENEN | 7 |
| JATINEGARA | 7 |
| PULO GADUNG | 7 |
| GROGOL PETAMBURAN | 6 |
| KEBON JERUK | 6 |
| KEBAYORAN LAMA | 6 |
| PASAR MINGGU | 6 |
| TEBET | 6 |
| MATRAMAN | 6 |
| KELAPA GADING | 6 |
| PADEMANGAN | 6 |
| PENJARINGAN | 6 |
| CENGKARENG | 5 |
| PALMERAH | 5 |
| TAMAN SARI | 5 |
| TAMBORA | 5 |
| CEMPAKA PUTIH | 5 |
| MENTENG | 5 |
| SAWAH BESAR | 5 |
| TANAH ABANG | 5 |
| CILANDAK | 5 |
| MAMPANG PRAPATAN | 5 |
| PANCORAN | 5 |
| KEBAYORAN BARU | 4 |
| CAKUNG | 4 |
| DUREN SAWIT | 4 |
| MAKASAR | 4 |
| PASAR REBO | 4 |
| TANJUNG PRIOK | 4 |
| KEMBANGAN | 3 |
| JOHAR BARU | 3 |
| JAGAKARSA | 3 |
| PESANGGRAHAN | 3 |
| CIPAYUNG | 3 |
| CIRACAS | 3 |
| CILINCING | 3 |
| KOJA | 3 |
| KALIDERES | 2 |
15.4 Uji Moran’s I
##
## Moran I test under randomisation
##
## data: moran_map$rata_rata
## weights: lw_jakarta
##
## Moran I statistic standard deviate = 1.7765, p-value = 0.03783
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic Expectation Variance
## 0.135438804 -0.025000000 0.008156469
15.5 Ringkasan Moran’s I
tibble(
Moran_I = as.numeric(moran_result$estimate[1]),
Expected_I = as.numeric(moran_result$estimate[2]),
Variance = as.numeric(moran_result$estimate[3]),
P_value = moran_result$p.value
) |>
mutate(across(where(is.numeric), ~ round(.x, 4))) |>
kable(caption = "Ringkasan Global Moran's I") |>
kable_styling(full_width = FALSE)| Moran_I | Expected_I | Variance | P_value |
|---|---|---|---|
| 0.1354 | -0.025 | 0.0082 | 0.0378 |
Jika Moran’s I positif dan signifikan, terdapat indikasi pengelompokan spasial nilai yang serupa. Jika tidak signifikan, belum terdapat bukti statistik yang cukup untuk menyatakan adanya autokorelasi spasial global.
16 Local Moran’s I
Local Moran’s I digunakan untuk mengetahui lokasi spesifik yang membentuk pengelompokan spasial.
local_moran <- localmoran(
moran_map$rata_rata,
lw_jakarta,
zero.policy = TRUE
)
moran_map <- moran_map |>
mutate(
local_I = local_moran[, "Ii"],
local_z = local_moran[, "Z.Ii"],
local_p = local_moran[, "Pr(z != E(Ii))"]
)16.1 Klasifikasi Cluster
nilai_rata2 <- mean(moran_map$rata_rata, na.rm = TRUE)
moran_map <- moran_map |>
mutate(
lag_rata_rata = lag.listw(
lw_jakarta,
rata_rata,
zero.policy = TRUE
),
cluster = case_when(
rata_rata >= nilai_rata2 &
lag_rata_rata >= nilai_rata2 &
local_p < 0.05 ~ "High-High",
rata_rata < nilai_rata2 &
lag_rata_rata < nilai_rata2 &
local_p < 0.05 ~ "Low-Low",
rata_rata >= nilai_rata2 &
lag_rata_rata < nilai_rata2 &
local_p < 0.05 ~ "High-Low",
rata_rata < nilai_rata2 &
lag_rata_rata >= nilai_rata2 &
local_p < 0.05 ~ "Low-High",
TRUE ~ "Tidak signifikan"
)
)16.2 Ringkasan Cluster
moran_map |>
st_drop_geometry() |>
count(cluster) |>
arrange(desc(n)) |>
kable(
col.names = c("Kategori Cluster", "Jumlah Kecamatan"),
caption = "Klasifikasi Local Spatial Autocorrelation"
) |>
kable_styling(full_width = FALSE)| Kategori Cluster | Jumlah Kecamatan |
|---|---|
| Tidak signifikan | 37 |
| High-High | 3 |
| High-Low | 1 |
17 Peta Local Moran’s I
ggplot(moran_map, aes(fill = cluster)) +
geom_sf(color = "white", linewidth = 0.3) +
labs(
title = "Local Moran's I Volume Sampah Sungai",
subtitle = "Identifikasi pola pengelompokan spasial",
fill = "Cluster",
x = NULL, y = NULL
) +
facet_wrap(~ kota_shp) +
theme_minimal() +
theme(
axis.text = element_blank(),
panel.grid = element_blank(),
strip.text = element_text(face = "bold")
)Pola High-High menunjukkan kecamatan dengan volume
relatif tinggi yang dikelilingi kecamatan dengan volume relatif tinggi.
Pola Low-Low menunjukkan kecamatan dengan volume relatif
rendah yang berdekatan dengan kecamatan bernilai rendah.
High-Low dan Low-High menunjukkan
ketidaksesuaian antara suatu kecamatan dan wilayah di sekitarnya.
18 Peta Nilai Local Moran’s I
ggplot(moran_map, aes(fill = local_I)) +
geom_sf(color = "white", linewidth = 0.3) +
scale_fill_viridis_c(
option = "C",
name = "Local Moran's I"
) +
labs(
title = "Distribusi Local Moran's I",
subtitle = "Kekuatan autokorelasi spasial lokal",
x = NULL, y = NULL
) +
facet_wrap(~ kota_shp) +
theme_minimal() +
theme(
axis.text = element_blank(),
panel.grid = element_blank(),
strip.text = element_text(face = "bold")
)19 Kecamatan dengan Volume Tertinggi
data_spasial_kecamatan |>
arrange(desc(rata_rata)) |>
slice_head(n = 10) |>
mutate(rata_rata = round(rata_rata, 2)) |>
select(wilayah, kecamatan, rata_rata) |>
kable(
col.names = c("Kota Administrasi", "Kecamatan", "Rata-rata Volume"),
caption = "10 Kecamatan dengan Rata-Rata Volume Sampah Tertinggi"
) |>
kable_styling(
full_width = FALSE,
bootstrap_options = c("striped", "hover")
)| Kota Administrasi | Kecamatan | Rata-rata Volume |
|---|---|---|
| KOTA ADM. JAKARTA SELATAN | JAGAKARSA | 83.37 |
| KOTA ADM. JAKARTA UTARA | PENJARINGAN | 63.20 |
| KOTA ADM. JAKARTA TIMUR | CAKUNG | 58.67 |
| KOTA ADM. JAKARTA BARAT | CENGKARENG | 57.86 |
| KOTA ADM. JAKARTA BARAT | KEMBANGAN | 46.52 |
| KOTA ADM. JAKARTA UTARA | TANJUNG PRIOK | 44.30 |
| KOTA ADM. JAKARTA BARAT | KEBON JERUK | 42.56 |
| KOTA ADM. JAKARTA TIMUR | KRAMATJATI | 39.21 |
| KOTA ADM. JAKARTA BARAT | GROGOL PETAMBURAN | 34.71 |
| KOTA ADM. JAKARTA BARAT | KALIDERES | 34.62 |
20 Kecamatan dengan Volume Terendah
data_spasial_kecamatan |>
arrange(rata_rata) |>
slice_head(n = 10) |>
mutate(rata_rata = round(rata_rata, 2)) |>
select(wilayah, kecamatan, rata_rata) |>
kable(
col.names = c("Kota Administrasi", "Kecamatan", "Rata-rata Volume"),
caption = "10 Kecamatan dengan Rata-Rata Volume Sampah Terendah"
) |>
kable_styling(
full_width = FALSE,
bootstrap_options = c("striped", "hover")
)| Kota Administrasi | Kecamatan | Rata-rata Volume |
|---|---|---|
| KOTA ADM. JAKARTA SELATAN | PANCORAN | 15.74 |
| KOTA ADM. JAKARTA TIMUR | CIPAYUNG | 16.87 |
| KOTA ADM. JAKARTA PUSAT | CEMPAKA PUTIH | 17.91 |
| KOTA ADM. JAKARTA TIMUR | CIRACAS | 18.64 |
| KOTA ADM. JAKARTA TIMUR | MATRAMAN | 19.93 |
| KOTA ADM. JAKARTA SELATAN | SETIABUDI | 20.38 |
| KOTA ADM. JAKARTA SELATAN | KEBAYORAN LAMA | 21.37 |
| KOTA ADM. JAKARTA PUSAT | SENEN | 21.43 |
| KOTA ADM. JAKARTA TIMUR | JATINEGARA | 21.44 |
| KOTA ADM. JAKARTA SELATAN | PASAR MINGGU | 21.51 |
21 Ringkasan Hasil
tibble(
indikator = c(
"Jumlah observasi",
"Jumlah kecamatan",
"Jumlah kota administrasi",
"Periode awal",
"Periode akhir",
"Mean",
"Median",
"Standar deviasi",
"Minimum",
"Maksimum",
"IQR",
"Jumlah outlier"
),
nilai = c(
nrow(data),
n_distinct(data$kecamatan),
n_distinct(data$wilayah),
format(min(data$tanggal), "%B %Y"),
format(max(data$tanggal), "%B %Y"),
round(mean(data$rata_rata, na.rm = TRUE), 2),
round(median(data$rata_rata, na.rm = TRUE), 2),
round(sd(data$rata_rata, na.rm = TRUE), 2),
round(min(data$rata_rata, na.rm = TRUE), 2),
round(max(data$rata_rata, na.rm = TRUE), 2),
round(IQR(data$rata_rata, na.rm = TRUE), 2),
sum(data_outlier$status_outlier != "Normal")
)
) |>
kable(
col.names = c("Indikator", "Nilai"),
caption = "Ringkasan Hasil Eksplorasi Data"
) |>
kable_styling(full_width = FALSE)| Indikator | Nilai |
|---|---|
| Jumlah observasi | 1302 |
| Jumlah kecamatan | 46 |
| Jumlah kota administrasi | 5 |
| Periode awal | January 2024 |
| Periode akhir | July 2026 |
| Mean | 30.38 |
| Median | 20.71 |
| Standar deviasi | 35.82 |
| Minimum | 0.47 |
| Maksimum | 316.87 |
| IQR | 13.95 |
| Jumlah outlier | 132 |
22 Kesimpulan
Berdasarkan hasil eksplorasi, volume sampah sungai di DKI Jakarta memiliki variasi antarobservasi, antarperiode, dan antarwilayah. Statistik deskriptif memberikan gambaran mengenai kecenderungan pusat dan penyebaran data, sedangkan histogram dan boxplot memperlihatkan distribusi serta observasi ekstrem.
Analisis time series digunakan untuk melihat perubahan volume sampah dari waktu ke waktu, sedangkan ACF digunakan untuk mengevaluasi ketergantungan antarperiode.
Pada aspek spasial, peta tematik memperlihatkan variasi volume sampah
antar kecamatan. Global Moran’s I digunakan untuk menguji autokorelasi
spasial secara keseluruhan, sedangkan Local Moran’s I digunakan untuk
mengidentifikasi pola pengelompokan lokal seperti
High-High, Low-Low, High-Low, dan
Low-High.
Secara keseluruhan, kombinasi analisis statistik, temporal, dan geospasial memberikan gambaran yang lebih lengkap mengenai karakteristik volume sampah sungai di DKI Jakarta.