# A tibble: 6 × 6
Provinsi KOTA AHH RLS PPK IPM
<chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 Jawa Barat BANDUNG 74.9 9.1 11018 73.7
2 Jawa Barat BANDUNG BARAT 74.8 8.23 9392 69.6
3 Jawa Barat BEKASI 75.1 9.57 12123 75.8
4 Jawa Barat BOGOR 74.7 8.37 11153 71.8
5 Jawa Barat CIAMIS 75.0 8.09 9750 72.0
6 Jawa Barat CIANJUR 74.6 7.22 8626 66.6
library(ggplot2)library(gridExtra)library(grid)# Function to Create Blue Histogram with Gridlinesplot_histogram <-function(data, variable_name) {ggplot(data, aes_string(x = variable_name)) +geom_histogram(fill ="skyblue", color ="white", bins =30) +# Adjust bins as neededlabs(x = variable_name, y ="Frequency") +theme_minimal() +# Clean themetheme(panel.grid.major.y =element_line(color ="lightgray")) # Add y-axis gridlines}# Create Histograms for each variablea <-plot_histogram(df_jabar, "AHH")b <-plot_histogram(df_jabar, "RLS")d <-plot_histogram(df_jabar, "PPK")e <-plot_histogram(df_jabar, "IPM")# Combine the plots into one frame with a titlegrid.arrange(arrangeGrob(a, b, d, e, ncol =2),top =textGrob("", gp =gpar(fontsize =16, fontface ="bold")))
library(tidyverse)library(dplyr)# Membuat kolom status IPM berdasarkan rentang IPM yang ditentukandf_jabar <- df_jabar %>%mutate(rentang_IPM =case_when( IPM >=80~"Sangat Tinggi", IPM >=70& IPM <80~"Tinggi", IPM >=60& IPM <70~"Sedang", IPM <60~"Rendah" ))if ("IPM_Kategori"%in%names(df_jabar)) { df_jabar <- df_jabar[, !names(df_jabar) %in%"IPM_Kategori"]}df_jabar <- df_jabar %>%arrange(desc(IPM))head(df_jabar,5)
# A tibble: 5 × 7
Provinsi KOTA AHH RLS PPK IPM rentang_IPM
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
1 Jawa Barat KOTA BANDUNG 75.5 11.1 18236 83.0 Sangat Tinggi
2 Jawa Barat KOTA BEKASI 75.9 11.7 16479 83.0 Sangat Tinggi
3 Jawa Barat KOTA DEPOK 75.5 11.6 16279 82.4 Sangat Tinggi
4 Jawa Barat KOTA CIMAHI 75.3 11.4 12883 79.5 Tinggi
5 Jawa Barat KOTA BOGOR 75.5 10.6 12656 77.8 Tinggi
library(tidyverse)library(dplyr)library(corrplot)numeric_df_jabar <- df_jabar %>% dplyr::select(-IPM) %>% dplyr::select_if(is.numeric)# Menghitung matriks korelasicor_matrix <-cor(numeric_df_jabar, use ="complete.obs")corrplot(cor_matrix, method ="color", col =colorRampPalette(c("skyblue", "white", "orange"))(200), type ="upper", order ="hclust", tl.col ="black", tl.srt =45, addCoef.col ="black", number.cex =0.7)
head(df_jabar)
# A tibble: 6 × 7
Provinsi KOTA AHH RLS PPK IPM rentang_IPM
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
1 Jawa Barat KOTA BANDUNG 75.5 11.1 18236 83.0 Sangat Tinggi
2 Jawa Barat KOTA BEKASI 75.9 11.7 16479 83.0 Sangat Tinggi
3 Jawa Barat KOTA DEPOK 75.5 11.6 16279 82.4 Sangat Tinggi
4 Jawa Barat KOTA CIMAHI 75.3 11.4 12883 79.5 Tinggi
5 Jawa Barat KOTA BOGOR 75.5 10.6 12656 77.8 Tinggi
6 Jawa Barat KOTA CIREBON 75.2 10.4 12506 76.5 Tinggi
summary(df_jabar2)
AHH RLS PPK IPM
Min. :73.87 Min. : 6.940 Min. : 8562 Min. :66.55
1st Qu.:74.69 1st Qu.: 7.865 1st Qu.: 9880 1st Qu.:69.50
Median :74.89 Median : 8.230 Median :11136 Median :72.09
Mean :74.93 Mean : 8.870 Mean :11526 Mean :73.25
3rd Qu.:75.08 3rd Qu.: 9.970 3rd Qu.:12449 3rd Qu.:76.04
Max. :75.86 Max. :11.660 Max. :18236 Max. :83.04
library(ggplot2)library(tidyverse)# Mengubah dataframe ke format long untuk ggplotdf_long <- scaled_jabar %>%pivot_longer(cols =c(AHH, RLS, PPK), names_to ="Variable", values_to ="Value")# Membuat boxplot dengan ggplotboxplot <-ggplot(df_long, aes(x = Variable, y = Value, fill = Variable)) +geom_boxplot(outlier.color ="red", outlier.shape =16, outlier.size =2) +labs(title ="Boxplot for AHH, RLS, PPK", x ="Variable", y ="Value") +theme_minimal() +scale_fill_brewer(palette ="Pastel1") +theme(legend.position ="none")# Menampilkan boxplotprint(boxplot)
# Pilih k optimal berdasarkan Dunn Index (nilai tertinggi)best_dunn_index <- result[which.max(result$Dunn_Index), ]# Pilih k optimal berdasarkan Silhouette (nilai tertinggi)best_silhouette <- result[which.max(result$Silhouette), ]# Pilih k optimal berdasarkan Calinski-Harabasz (nilai tertinggi)best_calinski_harabasz <- result[which.max(result$Calinski_Harabasz), ]# Pilih k optimal berdasarkan Davies-Bouldin (nilai terendah)best_davies_bouldin <- result[which.min(result$Davies_Bouldin), ]# Pilih k optimal berdasarkan sw_sb (nilai terendah)best_sw_sb <- result[which.min(result$sw_sb), ]# Gabungkan hasil-hasil tersebut dalam satu dataframebest_clusters <-data.frame(Metric =c("Dunn_Index", "Silhouette", "Calinski_Harabasz", "Davies_Bouldin", "sw_sb"),k =c(best_dunn_index$k, best_silhouette$k, best_calinski_harabasz$k, best_davies_bouldin$k, best_sw_sb$k),Score =c(best_dunn_index$Dunn_Index, best_silhouette$Silhouette, best_calinski_harabasz$Calinski_Harabasz, best_davies_bouldin$Davies_Bouldin, best_sw_sb$sw_sb))print(best_clusters)
dari empat indeks validitas internal terpilih metode ward dengan empat gerombol optimum
dendogram
# Memuat perpustakaan yang diperlukanlibrary(dplyr)library(heatmaply)library(RColorBrewer)# Menyiapkan data matriks untuk heatmapdata_matrix <-as.matrix(scaled_jabar)# Membuat heatmap dan dendrogram dengan metode linkage ward.D2heatmaply( data_matrix,colors =colorRampPalette(brewer.pal(3, "RdBu"))(256),k_col =2, k_row =4, # Menggunakan 4 cluster pada baris seperti yang ditentukanscale ="none",main ="Heatmap dan Dendrogram Berdasarkan Cluster",xlab ="Indikator",ylab ="Kota/Kabupaten",dendrogram ="both",fontsize_row =8,fontsize_col =10,labRow =rownames(data_matrix),labCol =colnames(data_matrix),hclust_method ="ward.D2"# Menentukan metode linkage ward.D2)
# Menyimpan heatmap ke file HTML dengan metode linkage ward.D2heatmaply( data_matrix,colors =colorRampPalette(brewer.pal(3, "RdBu"))(256),k_col =2, k_row =4, # Menggunakan 4 cluster pada baris seperti yang ditentukanscale ="none",main ="Heatmap dan Dendrogram Berdasarkan Cluster",xlab ="Indikator",ylab ="Kota/Kabupaten",dendrogram ="both",fontsize_row =8,fontsize_col =10,labRow =rownames(data_matrix),labCol =colnames(data_matrix),hclust_method ="ward.D2", # Menentukan metode linkage ward.D2#file = "heatmap_single_linkage_k4.html")
The "ward" method has been renamed to "ward.D"; note new "ward.D2"
The "ward" method has been renamed to "ward.D"; note new "ward.D2"
The "ward" method has been renamed to "ward.D"; note new "ward.D2"
The "ward" method has been renamed to "ward.D"; note new "ward.D2"
The "ward" method has been renamed to "ward.D"; note new "ward.D2"
The "ward" method has been renamed to "ward.D"; note new "ward.D2"
The "ward" method has been renamed to "ward.D"; note new "ward.D2"
K-means clustering with 4 clusters of sizes 1, 6, 17, 3
Cluster means:
AHH RLS PPK
1 -2.7310377 -0.6248829 -1.2515962
2 0.6136735 0.9911146 0.2727383
3 -0.3776323 -0.6236711 -0.4304364
4 1.8229152 1.7602012 2.3108616
Clustering vector:
BANDUNG BANDUNG BARAT BEKASI BOGOR
3 3 2 3
CIAMIS CIANJUR CIREBON GARUT
3 3 3 3
INDRAMAYU KARAWANG KOTA BANDUNG KOTA BANJAR
3 3 4 3
KOTA BEKASI KOTA BOGOR KOTA CIMAHI KOTA CIREBON
4 2 2 2
KOTA DEPOK KOTA SUKABUMI KOTA TASIKMALAYA KUNINGAN
4 2 2 3
MAJALENGKA PANGANDARAN PURWAKARTA SUBANG
3 3 3 3
SUKABUMI SUMEDANG TASIKMALAYA
3 3 1
Within cluster sum of squares by cluster:
[1] 0.0000000 3.0309365 8.4889402 0.9942159
(between_SS / total_SS = 84.0 %)
Available components:
[1] "cluster" "centers" "totss" "withinss" "tot.withinss"
[6] "betweenss" "size" "iter" "ifault"
k4_means$cluster
BANDUNG BANDUNG BARAT BEKASI BOGOR
3 3 2 3
CIAMIS CIANJUR CIREBON GARUT
3 3 3 3
INDRAMAYU KARAWANG KOTA BANDUNG KOTA BANJAR
3 3 4 3
KOTA BEKASI KOTA BOGOR KOTA CIMAHI KOTA CIREBON
4 2 2 2
KOTA DEPOK KOTA SUKABUMI KOTA TASIKMALAYA KUNINGAN
4 2 2 3
MAJALENGKA PANGANDARAN PURWAKARTA SUBANG
3 3 3 3
SUKABUMI SUMEDANG TASIKMALAYA
3 3 1
library(cluster)library(fpc)library(clusterSim)# Function to calculate S_W and S_Bcalculate_sw_sb_ratio <-function(data, kmeans_result) {# Total Sum of Squares tss <-sum((data -colMeans(data))^2)# Within-cluster Sum of Squares (S_W) sw <-sum(kmeans_result$withinss)# Between-cluster Sum of Squares (S_B) sb <- tss - sw# Ratio S_W / S_B ratio <- sw / sbreturn(list(S_W = sw, S_B = sb, ratio = ratio))}# Initialize an empty dataframe to store resultsinternal_metrics <-data.frame(K =integer(),Dunn_Index =numeric(),Silhouette =numeric(),Calinski_Harabasz =numeric(),Davies_Bouldin =numeric(),sw_sb =numeric())# List of k-means results for k = 3 and k = 4kmeans_list <-list(k3_means, k4_means)# Loop through the list of k-means resultsfor (k in3:4) { k_means <- kmeans_list[[k -2]]# Calculate internal validation metrics distance_matrix <-dist(scaled_jabar)# Ensure that the length of the clustering vector matches the number of rows in the distance matrixif(length(k_means$cluster) !=nrow(as.matrix(distance_matrix))) {stop("The length of the clustering vector does not match the number of rows in the distance matrix for k = ", k) } kmeans_internal <-cluster.stats(distance_matrix, k_means$cluster, silhouette =TRUE) kmeans_db <-index.DB(scaled_jabar, k_means$cluster, distance_matrix, centrotypes ="centroids", p =2, q =2) sw_sb_k <-calculate_sw_sb_ratio(scaled_jabar, k_means)# Extract metrics dunn_index <-round(kmeans_internal$dunn, 3) silhouette_score <-round(kmeans_internal$avg.silwidth, 3) calinski_harabasz_index <-round(kmeans_internal$ch, 3) db_index <-round(kmeans_db$DB, 3) swsb_ratio <-round(sw_sb_k$ratio, 3)# Add to the dataframe internal_metrics <-rbind(internal_metrics, data.frame(K = k,Dunn_Index = dunn_index,Silhouette = silhouette_score,Calinski_Harabasz = calinski_harabasz_index,Davies_Bouldin = db_index,sw_sb = swsb_ratio ))}# Print the dataframeprint(internal_metrics)
internal_metrics_kmeans <- internal_metrics# Determine the optimal k based on different criteriaoptimal_k_silhouette <- internal_metrics_kmeans$K[which.max(internal_metrics_kmeans$Silhouette)]optimal_k_dunn <- internal_metrics_kmeans$K[which.max(internal_metrics_kmeans$Dunn_Index)]optimal_k_ch <- internal_metrics_kmeans$K[which.max(internal_metrics_kmeans$Calinski_Harabasz)]optimal_k_db <- internal_metrics_kmeans$K[which.min(internal_metrics_kmeans$Davies_Bouldin)]optimal_k_sw_sb <- internal_metrics_kmeans$K[which.min(internal_metrics_kmeans$sw_sb)]# Print the optimal k for each metriccat("Optimal k based on Silhouette Score:", optimal_k_silhouette, "\n")
Optimal k based on Silhouette Score: 3
cat("Optimal k based on Dunn Index:", optimal_k_dunn, "\n")
Optimal k based on Dunn Index: 4
cat("Optimal k based on Calinski-Harabasz Index:", optimal_k_ch, "\n")
Optimal k based on Calinski-Harabasz Index: 4
cat("Optimal k based on Davies-Bouldin Index:", optimal_k_db, "\n")
Optimal k based on Davies-Bouldin Index: 4
cat("Optimal k based on sw/sb Ratio:", optimal_k_sw_sb, "\n")
# Menentukan metode terbaik untuk setiap metrikbest_dunn_index <- score_data$method[which.max(score_data$Dunn_Index)]best_silhouette <- score_data$method[which.max(score_data$Silhouette)]best_calinski_harabasz <- score_data$method[which.max(score_data$Calinski_Harabasz)]best_davies_bouldin <- score_data$method[which.min(score_data$Davies_Bouldin)]best_sw_sb <- score_data$method[which.min(score_data$sw_sb)]# Membuat data frame hasil terbaikbest_algorithms <-data.frame(Metric =c("Dunn_Index", "Silhouette", "Calinski_Harabasz", "Davies_Bouldin", "sw_sb"),Best_Method =c(best_dunn_index, best_silhouette, best_calinski_harabasz, best_davies_bouldin, best_sw_sb))# Menampilkan data frame hasil terbaikprint(best_algorithms)
library(dplyr)merged_jabar <- gdf %>%right_join(df_jabar2, by =c("KAB_KOTA"="KOTA"))head(merged_jabar,10)
Simple feature collection with 10 features and 8 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 106.4011 ymin: -7.74015 xmax: 108.8338 ymax: -5.91377
Geodetic CRS: WGS 84
KAB_KOTA Provinsi AHH RLS PPK IPM rentang_IPM g4_kmeans
1 BANDUNG Jawa Barat 74.92 9.10 11018 73.74 Tinggi 3
2 BANDUNG BARAT Jawa Barat 74.78 8.23 9392 69.61 Sedang 3
3 BEKASI Jawa Barat 75.09 9.57 12123 75.76 Tinggi 2
4 BOGOR Jawa Barat 74.67 8.37 11153 71.78 Tinggi 3
5 CIAMIS Jawa Barat 74.96 8.09 9750 72.05 Tinggi 3
6 CIANJUR Jawa Barat 74.61 7.22 8626 66.55 Sedang 3
7 CIREBON Jawa Barat 74.71 7.64 11128 70.95 Tinggi 3
8 GARUT Jawa Barat 74.66 7.84 8685 68.11 Sedang 3
9 INDRAMAYU Jawa Barat 74.61 6.94 10580 69.25 Sedang 3
10 KARAWANG Jawa Barat 74.90 8.04 12392 72.35 Tinggi 3
geometry
1 MULTIPOLYGON (((107.7327 -6...
2 MULTIPOLYGON (((107.4393 -6...
3 MULTIPOLYGON (((107.0314 -5...
4 MULTIPOLYGON (((106.9709 -6...
5 MULTIPOLYGON (((108.5653 -7...
6 MULTIPOLYGON (((107.23 -6.6...
7 MULTIPOLYGON (((108.6733 -6...
8 MULTIPOLYGON (((107.918 -6....
9 MULTIPOLYGON (((108.3674 -6...
10 MULTIPOLYGON (((107.1123 -5...
boxplot
# Membuat boxplot untuk variabel AHHp1 <-ggplot(sorted_jabar, aes(x = g4_kmeans, y = AHH, fill = g4_kmeans)) +geom_boxplot() +scale_fill_manual(values =c("G1"="#bdd7e7", "G2"="#6baed6", "G3"="#3182bd", "G4"="#08519c")) +theme_minimal() +labs(title ="",x ="",y ="AHH") +theme(legend.position ="none")# Membuat boxplot untuk variabel RLSp2 <-ggplot(sorted_jabar, aes(x = g4_kmeans, y = RLS, fill = g4_kmeans)) +geom_boxplot() +scale_fill_manual(values =c("G1"="#bdd7e7", "G2"="#6baed6", "G3"="#3182bd", "G4"="#08519c")) +theme_minimal() +labs(title ="",x ="",y ="RLS") +theme(legend.position ="none")# Membuat boxplot untuk variabel PPKp3 <-ggplot(sorted_jabar, aes(x = g4_kmeans, y = PPK, fill = g4_kmeans)) +geom_boxplot() +scale_fill_manual(values =c("G1"="#bdd7e7", "G2"="#6baed6", "G3"="#3182bd", "G4"="#08519c")) +theme_minimal() +labs(title ="",x ="",y ="PPK") +theme(legend.position ="none")# Membuat boxplot untuk variabel IPMp4 <-ggplot(sorted_jabar, aes(x = g4_kmeans, y = IPM, fill = g4_kmeans)) +geom_boxplot() +scale_fill_manual(values =c("G1"="#bdd7e7", "G2"="#6baed6", "G3"="#3182bd", "G4"="#08519c")) +theme_minimal() +labs(title ="",x ="Cluster",y ="IPM") +theme(legend.position ="none")grid.arrange(p1, p2, p3, nrow =2)
# Membuat plot bar untuk variabel IPMggplot(df_ipm_means, aes(x =g4_kmeans, y = IPM, fill = g4_kmeans)) +geom_bar(stat ="identity") +scale_fill_manual(values =c("G1"="#bdd7e7", "G2"="#6baed6", "G3"="#3182bd", "G4"="#08519c")) +theme_minimal() +labs(title ="Rataan IPM Berdasarkan Cluster",x ="Cluster",y ="Rataan IPM") +theme(legend.position ="none") +geom_text(aes(label =round(IPM, 2)), vjust =-0.5)
# Memuat perpustakaan yang diperlukanlibrary(dplyr)library(tidyr)library(ggplot2)# Menghitung rataan tiap indikator per clusterdf_means <- sorted_jabar %>%group_by(g4_kmeans) %>%summarise(AHH =mean(AHH, na.rm =TRUE),RLS =mean(RLS, na.rm =TRUE),PPK =mean(PPK, na.rm =TRUE)#IPM = mean(IPM, na.rm = TRUE) )# Mengubah dataframe dari format lebar ke panjang untuk ggplotdf_means_long <- df_means %>%pivot_longer(cols = AHH:PPK, names_to ="Indikator", values_to ="Rata-rata")# Membuat plot bar untuk rataan tiap indikatorggplot(df_means_long, aes(x = g4_kmeans, y =`Rata-rata`, fill = g4_kmeans)) +geom_bar(stat ="identity", position ="dodge") +facet_wrap(~ Indikator, scales ="free_y") +scale_fill_manual(values =c("G1"="#bdd7e7", "G2"="#6baed6", "G3"="#3182bd", "G4"="#08519c")) +theme_minimal() +labs(title ="",x ="Cluster",y ="Rata-rata") +theme(legend.position ="none") +geom_text(aes(label =round(`Rata-rata`, 2)), position =position_dodge(width =0.9), vjust =-0.5)
# Memuat perpustakaan yang diperlukanlibrary(sf)library(ggplot2)library(gridExtra)# Membuat plot untuk rentang_ipmp1 <-ggplot(merged_jabar2) +geom_sf(aes(fill = rentang_IPM)) +scale_fill_manual(values =c("Sangat Tinggi"="#bdd7e7", "Tinggi"="#6baed6", "Sedang"="#3182bd", "Rendah"="#08519c"),name ="Rentang IPM") +theme_minimal() +labs(title ="Sebaran Kota Berdasarkan status IPM",x ="Longitude",y ="Latitude") +theme(panel.background =element_blank())# Membuat plot untuk clusterp2 <-ggplot(merged_jabar2) +geom_sf(aes(fill = g4_kmeans)) +scale_fill_manual(values =c("G1"="#bdd7e7", "G2"="#6baed6", "G3"="#3182bd", "G4"="#08519c"),name ="Gerombol") +theme_minimal() +labs(title ="Sebaran Kota Berdasarkan k-means",x ="Longitude",y ="Latitude") +theme(panel.background =element_blank())# Menampilkan kedua plot dalam satu gridgrid.arrange(p1, p2, ncol =1)