library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(readxl)
library(tidyr)
library(ggplot2)
library(cluster)
## Warning: package 'cluster' was built under R version 4.5.2
library(factoextra)
## Warning: package 'factoextra' was built under R version 4.5.2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(NbClust)
## Warning: package 'NbClust' was built under R version 4.5.2
library(readr)
library(reshape2)
##
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
##
## smiths
library(fmsb)
## Warning: package 'fmsb' was built under R version 4.5.2
library(cluster)
library(tibble)
df <- read_excel("C:\\Users\\Hafizh Fadhlah\\OneDrive\\Documents\\0_df_long.xlsx")
str(df)
## tibble [340,620 × 9] (S3: tbl_df/tbl/data.frame)
## $ KabKot : chr [1:340620] "Kab. Aceh Barat" "Kab. Aceh Barat" "Kab. Aceh Barat" "Kab. Aceh Barat" ...
## $ Tahun : num [1:340620] 2022 2022 2022 2022 2022 ...
## $ Bulan : chr [1:340620] "Januari" "Januari" "Januari" "Januari" ...
## $ Produk : chr [1:340620] "Beras Premium" "Beras Medium" "Bawang Merah" "Bawang Putih (Bonggol)" ...
## $ Harga : chr [1:340620] "11429" "9979" "31000" "28636" ...
## $ Kategori: chr [1:340620] "Beras" "Beras" "Bawang" "Bawang" ...
## $ KodeBPS : chr [1:340620] "11.05" "11.05" "11.05" "11.05" ...
## $ KodeProv: num [1:340620] 11 11 11 11 11 11 11 11 11 11 ...
## $ NamaProv: chr [1:340620] "Aceh" "Aceh" "Aceh" "Aceh" ...
head(df)
## # A tibble: 6 × 9
## KabKot Tahun Bulan Produk Harga Kategori KodeBPS KodeProv NamaProv
## <chr> <dbl> <chr> <chr> <chr> <chr> <chr> <dbl> <chr>
## 1 Kab. Aceh Barat 2022 Januari Beras … 11429 Beras 11.05 11 Aceh
## 2 Kab. Aceh Barat 2022 Januari Beras … 9979 Beras 11.05 11 Aceh
## 3 Kab. Aceh Barat 2022 Januari Bawang… 31000 Bawang 11.05 11 Aceh
## 4 Kab. Aceh Barat 2022 Januari Bawang… 28636 Bawang 11.05 11 Aceh
## 5 Kab. Aceh Barat 2022 Januari Cabai … 19409 Cabai 11.05 11 Aceh
## 6 Kab. Aceh Barat 2022 Januari Cabai … 45706 Cabai 11.05 11 Aceh
Data yang akan digunakan pada analisis ini hanya data beras di setiap provinsi pada tahun 2024
df_beras <- df %>%
filter(Tahun == 2024,
grepl("Beras", Kategori, ignore.case = TRUE))
df_beras
## # A tibble: 11,964 × 9
## KabKot Tahun Bulan Produk Harga Kategori KodeBPS KodeProv NamaProv
## <chr> <dbl> <chr> <chr> <chr> <chr> <chr> <dbl> <chr>
## 1 Kab. Aceh Barat 2024 Januari Beras… 14655 Beras 11.05 11 Aceh
## 2 Kab. Aceh Barat 2024 Januari Beras… 12811 Beras 11.05 11 Aceh
## 3 Kab. Aceh Barat 2024 Februa… Beras… 14658 Beras 11.05 11 Aceh
## 4 Kab. Aceh Barat 2024 Februa… Beras… 13233 Beras 11.05 11 Aceh
## 5 Kab. Aceh Barat 2024 Maret Beras… 14631 Beras 11.05 11 Aceh
## 6 Kab. Aceh Barat 2024 Maret Beras… 13249 Beras 11.05 11 Aceh
## 7 Kab. Aceh Barat 2024 April Beras… 14670 Beras 11.05 11 Aceh
## 8 Kab. Aceh Barat 2024 April Beras… 13104 Beras 11.05 11 Aceh
## 9 Kab. Aceh Barat 2024 Mei Beras… 14797 Beras 11.05 11 Aceh
## 10 Kab. Aceh Barat 2024 Mei Beras… 13532 Beras 11.05 11 Aceh
## # ℹ 11,954 more rows
length(df)
## [1] 9
df_beras <- df_beras %>%
group_by(NamaProv) %>%
mutate(Harga = ifelse(is.na(Harga),
mean(Harga, na.rm = TRUE),
Harga)) %>%
ungroup()
Penanganan missing value yang dilakukan adalah mengganti nilai NA pada variabel harga sebuah provinsi dengan nilai rata-rata harga beras pada provinsi tersebut.
sum(is.na(df_beras$Harga))
## [1] 0
Dilakukan pengecekan kembali untuk memastikan tidak ada lagi nilai NA dan terbukti jumlah nilai NA adalah 0
df_beras <- df_beras %>%
mutate(Harga = gsub("[^0-9]", "", Harga), # hapus karakter non-digit
Harga = as.numeric(Harga))
str(df_beras$Harga)
## num [1:11964] 14655 12811 14658 13233 14631 ...
Dilakukan pembersihan pada kolom Harga agar semua data menjadi numerik. Data-data yang memiliki simbol atau huruf akan dibersihkan dan menyisakan numeriknya saja
df_cluster <- df_beras %>%
group_by(NamaProv) %>%
summarise(Rata_Harga = mean(Harga, na.rm = TRUE))
df_cluster
## # A tibble: 34 × 2
## NamaProv Rata_Harga
## <chr> <dbl>
## 1 Aceh 13975.
## 2 Bali 14765.
## 3 Banten 13979.
## 4 Bengkulu 14410.
## 5 DI Yogyakarta 13995.
## 6 DKI Jakarta 14952.
## 7 Gorontalo 14631
## 8 Jambi 13972.
## 9 Jawa Barat 14072.
## 10 Jawa Tengah 14153.
## # ℹ 24 more rows
Pada perhitungan rata-rata di atas, terdapat satu provinsi yang bernama NA. Setelah dicek satu persatu sesuai dengan data 34 provinsi pertama di Indonesia, provinsi yang NA tersebut kemungkinan adalah Kalimantan Utara
df_cluster %>% filter(is.na(NamaProv))
## # A tibble: 0 × 2
## # ℹ 2 variables: NamaProv <chr>, Rata_Harga <dbl>
df_cluster %>% filter(NamaProv == "NA")
## # A tibble: 1 × 2
## NamaProv Rata_Harga
## <chr> <dbl>
## 1 NA 16422.
Kembali dicek juga apakah masih ada nilai na pada data dan hasilnya adalah 0. Namun, terdapat data yang dinamakan NA dengan rata-rata harga 16422.42
df_cluster2 <- df_cluster %>%
mutate(NamaProv = if_else(NamaProv == "NA",
"Kalimantan Utara",
NamaProv))
df_cluster2
## # A tibble: 34 × 2
## NamaProv Rata_Harga
## <chr> <dbl>
## 1 Aceh 13975.
## 2 Bali 14765.
## 3 Banten 13979.
## 4 Bengkulu 14410.
## 5 DI Yogyakarta 13995.
## 6 DKI Jakarta 14952.
## 7 Gorontalo 14631
## 8 Jambi 13972.
## 9 Jawa Barat 14072.
## 10 Jawa Tengah 14153.
## # ℹ 24 more rows
Kemudian, data yang dinamakan NA tadi diganti dengan Kalimantan Utara yang sebelumnya tidak ada di kolom NamaProv
df_clberas <- df_beras %>%
group_by(NamaProv) %>%
summarise(Rata_Harga = mean(Harga, na.rm = TRUE)) %>%
arrange(Rata_Harga)
df_clharga <- df_cluster2 %>%
select(Rata_Harga)
df_clberas
## # A tibble: 34 × 2
## NamaProv Rata_Harga
## <chr> <dbl>
## 1 Sumatera Selatan 13470.
## 2 Jawa Timur 13588.
## 3 Sulawesi Selatan 13734.
## 4 Sulawesi Tenggara 13894.
## 5 Lampung 13911.
## 6 Sulawesi Barat 13961.
## 7 Jambi 13972.
## 8 Aceh 13975.
## 9 Banten 13979.
## 10 DI Yogyakarta 13995.
## # ℹ 24 more rows
df_clharga
## # A tibble: 34 × 1
## Rata_Harga
## <dbl>
## 1 13975.
## 2 14765.
## 3 13979.
## 4 14410.
## 5 13995.
## 6 14952.
## 7 14631
## 8 13972.
## 9 14072.
## 10 14153.
## # ℹ 24 more rows
df_scaled <- scale(df_clharga)
df_scaled
## Rata_Harga
## [1,] -0.71719091
## [2,] -0.16549073
## [3,] -0.71434467
## [4,] -0.41350305
## [5,] -0.70325164
## [6,] -0.03472931
## [7,] -0.25895436
## [8,] -0.71941870
## [9,] -0.64932925
## [10,] -0.59273542
## [11,] -0.98767212
## [12,] 0.62467360
## [13,] -0.23457504
## [14,] 0.58249274
## [15,] 1.06425289
## [16,] 0.21825284
## [17,] 0.12651147
## [18,] -0.76198377
## [19,] 0.83382949
## [20,] 1.17168531
## [21,] 0.99218896
## [22,] -0.61938172
## [23,] -0.02330028
## [24,] 1.36288200
## [25,] 4.11994311
## [26,] -0.02576411
## [27,] -0.72708089
## [28,] -0.88540703
## [29,] -0.33141406
## [30,] -0.77352816
## [31,] -0.29871699
## [32,] 0.88705760
## [33,] -1.06997921
## [34,] -0.27601859
## attr(,"scaled:center")
## Rata_Harga
## 15001.78
## attr(,"scaled:scale")
## Rata_Harga
## 1431.83
fviz_nbclust(df_scaled, kmeans, method = "wss") +
ggtitle("Elbow Method untuk Menentukan Jumlah Cluster")
Dilihat dari grafik di atas, kemungkinan nilai k yang digunakan adalah k
= 4. Angka tersebut diambil ketika garis grafik mulai melandai yang
menandakan angka setelahnya akan menimbulkan masalah jika clusternya
terlalu banyak
k1 <- 4
set.seed(123)
km_model1 <- kmeans(df_clharga, centers = k1, nstart = 25)
km_model1$cluster
## [1] 1 4 1 4 1 4 4 1 1 1 1 3 4 3 3 4 4 1 3 3 3 1 4 3 2 4 1 1 4 1 4 3 1 4
sil1 <- silhouette(km_model1$cluster, dist(df_clharga))
mean(sil1[, 3])
## [1] 0.6596401
k2 <- 3
set.seed(123)
km_model2 <- kmeans(df_clharga, centers = k2, nstart = 25)
km_model2$cluster
## [1] 1 1 1 1 1 1 1 1 1 1 1 3 1 3 3 3 1 1 3 3 3 1 1 3 2 1 1 1 1 1 1 3 1 1
sil2 <- silhouette(km_model2$cluster, dist(df_clharga))
mean(sil2[, 3])
## [1] 0.6560839
k3 <- 5
set.seed(123)
km_model3 <- kmeans(df_clharga, centers = k3, nstart = 25)
km_model3$cluster
## [1] 5 1 5 1 5 1 1 5 5 5 5 4 1 4 3 4 4 5 3 3 3 5 1 3 2 1 5 5 1 5 1 3 5 1
sil3 <- silhouette(km_model3$cluster, dist(df_clharga))
mean(sil3[, 3])
## [1] 0.5996905
Kemudian, dilakukan pengecekan dengan silhoutte score untuk melihat nilai tertinggi pada K yang dipilih. Dapat dilihat bahwa nili k = 4 lebih baik diantara 2 nilai yang mengapitnya, yaitu K = 3 dan 5. Hasil ini menunjukkan K = 4 menunjukkan kualitas cluster terbaik dengan nilai 0.6596401
plot(sil1,
border = NA,
main = "Plot Silhouette – K-Means Clustering")
Dapat dilihat juga plot dari silhoutte score. Untuk cluster 1, skornya =
0.76 Untuk cluster 2, skornya= 0.00 dikarenakan hanya ada 1 provinsi.
Untuk cluster 3, skornya = 0.68. Dan untuk cluster 4, skornya 0.59. Plot
ini berfungsi untuk melihat seberapa rapat data terhadap clusternya
masing-masing dan seberapa jauh data tersebut dengan cluster lain
df_cluster2$cluster <- as.factor(km_model1$cluster)
ggplot(df_cluster2, aes(x = reorder(NamaProv, Rata_Harga), y = Rata_Harga, fill = cluster)) +
geom_col() +
coord_flip() +
scale_y_continuous(breaks = seq(0, 22000, by = 2000)) +
labs(title = "Cluster Harga Beras 2024 - Bar Plot")
ggplot(df_cluster2, aes(x = Rata_Harga,
y = cluster,
color = cluster)) +
geom_point(size = 3) +
labs(title = "K-Means Clustering Berdasarkan Harga Beras 2024",
x = "Rata-rata Harga Beras",
y = "Cluster") +
theme_minimal()
library(dplyr)
range_kmeans <- df_cluster2 %>%
group_by(cluster) %>%
summarise(
min_harga = min(Rata_Harga, na.rm = TRUE),
max_harga = max(Rata_Harga, na.rm = TRUE),
mean_harga = mean(Rata_Harga, na.rm = TRUE),
median_harga = median(Rata_Harga, na.rm = TRUE),
.groups = "drop"
)
range_kmeans
## # A tibble: 4 × 5
## cluster min_harga max_harga mean_harga median_harga
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 1 13470. 14153. 13909. 13972.
## 2 2 20901. 20901. 20901. 20901.
## 3 3 15836. 16953. 16348. 16347.
## 4 4 14410. 15314. 14797. 14715.
Cluster 1 (Merah) menunjukkan cluster dengan harga rendah, cluster 2 (Hijau) menunjukkan cluster dengan harga sangat tinggi, cluster 3 (Biru) menunjukkan harga cukup tinggi, dan cluster 4 (Ungu) menunjukkan harga menengah. Batas atas dan batas bawah masing-masing cluster juga dapat dilihat pada tebel yang ada diatas, dengan cluster 1 13469.75 sampai 14153.08, cluster 2 20900.84 (karena hanya 1 provinsi), cluster 3 15835.81 sampai 16953.19, dan cluster 4 14409.71 sampai 15314.28
fviz_nbclust(df_clharga, pam, method = "silhouette")
pam_model <- pam(df_scaled, k = 4)
df_cluster2$Cluster_PAM <- as.factor(pam_model$clustering)
sil_pam <- silhouette(pam_model)
sil_pam
## cluster neighbor sil_width
## 27 1 2 0.8263118
## 8 1 2 0.8251105
## 1 1 2 0.8241083
## 18 1 2 0.8220078
## 3 1 2 0.8219862
## 30 1 2 0.8176369
## 5 1 2 0.8102085
## 28 1 2 0.7572002
## 9 1 2 0.7278501
## 11 1 2 0.6957827
## 22 1 2 0.6635740
## 33 1 2 0.6413946
## 10 1 2 0.5893063
## 6 2 1 0.7291645
## 26 2 1 0.7280363
## 23 2 1 0.7271255
## 2 2 1 0.7096894
## 13 2 1 0.6717480
## 7 2 1 0.6470859
## 34 2 1 0.6219865
## 17 2 3 0.6178283
## 31 2 1 0.5768562
## 29 2 1 0.4897361
## 16 2 3 0.4536691
## 4 2 1 0.1565305
## 21 3 2 0.7907525
## 15 3 2 0.7861886
## 32 3 2 0.7693989
## 20 3 2 0.7569682
## 19 3 2 0.7412686
## 24 3 2 0.6790040
## 12 3 2 0.5151299
## 14 3 2 0.4371192
## 25 4 3 0.0000000
## attr(,"Ordered")
## [1] TRUE
## attr(,"call")
## pam(x = df_scaled, k = 4)
## attr(,"class")
## [1] "silhouette"
mean(sil_pam[,3])
## [1] 0.6596401
Sama seperti K-Means, nilai K yang digunakan untuk K-Medoids adalah K = 4
ggplot(df_cluster2, aes(x = reorder(NamaProv, Rata_Harga),
y = Rata_Harga,
fill = Cluster_PAM)) +
geom_col() +
coord_flip() +
labs(title = "Visualisasi Cluster – K-Medoids (Barplot)",
x = "Provinsi",
y = "Harga Beras 2024") + scale_y_continuous(breaks = seq(0, 22000, by = 2000))
theme_minimal()
## List of 136
## $ line :List of 6
## ..$ colour : chr "black"
## ..$ linewidth : num 0.5
## ..$ linetype : num 1
## ..$ lineend : chr "butt"
## ..$ arrow : logi FALSE
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_line" "element"
## $ rect :List of 5
## ..$ fill : chr "white"
## ..$ colour : chr "black"
## ..$ linewidth : num 0.5
## ..$ linetype : num 1
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_rect" "element"
## $ text :List of 11
## ..$ family : chr ""
## ..$ face : chr "plain"
## ..$ colour : chr "black"
## ..$ size : num 11
## ..$ hjust : num 0.5
## ..$ vjust : num 0.5
## ..$ angle : num 0
## ..$ lineheight : num 0.9
## ..$ margin : 'margin' num [1:4] 0points 0points 0points 0points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : logi FALSE
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ title : NULL
## $ aspect.ratio : NULL
## $ axis.title : NULL
## $ axis.title.x :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : NULL
## ..$ vjust : num 1
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 2.75points 0points 0points 0points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.title.x.top :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : NULL
## ..$ vjust : num 0
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 0points 0points 2.75points 0points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.title.x.bottom : NULL
## $ axis.title.y :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : NULL
## ..$ vjust : num 1
## ..$ angle : num 90
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 0points 2.75points 0points 0points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.title.y.left : NULL
## $ axis.title.y.right :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : NULL
## ..$ vjust : num 1
## ..$ angle : num -90
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 0points 0points 0points 2.75points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.text :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : chr "grey30"
## ..$ size : 'rel' num 0.8
## ..$ hjust : NULL
## ..$ vjust : NULL
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : NULL
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.text.x :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : NULL
## ..$ vjust : num 1
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 2.2points 0points 0points 0points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.text.x.top :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : NULL
## ..$ vjust : num 0
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 0points 0points 2.2points 0points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.text.x.bottom : NULL
## $ axis.text.y :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : num 1
## ..$ vjust : NULL
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 0points 2.2points 0points 0points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.text.y.left : NULL
## $ axis.text.y.right :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : num 0
## ..$ vjust : NULL
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 0points 0points 0points 2.2points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.text.theta : NULL
## $ axis.text.r :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : num 0.5
## ..$ vjust : NULL
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : 'margin' num [1:4] 0points 2.2points 0points 2.2points
## .. ..- attr(*, "unit")= int 8
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ axis.ticks : list()
## ..- attr(*, "class")= chr [1:2] "element_blank" "element"
## $ axis.ticks.x : NULL
## $ axis.ticks.x.top : NULL
## $ axis.ticks.x.bottom : NULL
## $ axis.ticks.y : NULL
## $ axis.ticks.y.left : NULL
## $ axis.ticks.y.right : NULL
## $ axis.ticks.theta : NULL
## $ axis.ticks.r : NULL
## $ axis.minor.ticks.x.top : NULL
## $ axis.minor.ticks.x.bottom : NULL
## $ axis.minor.ticks.y.left : NULL
## $ axis.minor.ticks.y.right : NULL
## $ axis.minor.ticks.theta : NULL
## $ axis.minor.ticks.r : NULL
## $ axis.ticks.length : 'simpleUnit' num 2.75points
## ..- attr(*, "unit")= int 8
## $ axis.ticks.length.x : NULL
## $ axis.ticks.length.x.top : NULL
## $ axis.ticks.length.x.bottom : NULL
## $ axis.ticks.length.y : NULL
## $ axis.ticks.length.y.left : NULL
## $ axis.ticks.length.y.right : NULL
## $ axis.ticks.length.theta : NULL
## $ axis.ticks.length.r : NULL
## $ axis.minor.ticks.length : 'rel' num 0.75
## $ axis.minor.ticks.length.x : NULL
## $ axis.minor.ticks.length.x.top : NULL
## $ axis.minor.ticks.length.x.bottom: NULL
## $ axis.minor.ticks.length.y : NULL
## $ axis.minor.ticks.length.y.left : NULL
## $ axis.minor.ticks.length.y.right : NULL
## $ axis.minor.ticks.length.theta : NULL
## $ axis.minor.ticks.length.r : NULL
## $ axis.line : list()
## ..- attr(*, "class")= chr [1:2] "element_blank" "element"
## $ axis.line.x : NULL
## $ axis.line.x.top : NULL
## $ axis.line.x.bottom : NULL
## $ axis.line.y : NULL
## $ axis.line.y.left : NULL
## $ axis.line.y.right : NULL
## $ axis.line.theta : NULL
## $ axis.line.r : NULL
## $ legend.background : list()
## ..- attr(*, "class")= chr [1:2] "element_blank" "element"
## $ legend.margin : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
## ..- attr(*, "unit")= int 8
## $ legend.spacing : 'simpleUnit' num 11points
## ..- attr(*, "unit")= int 8
## $ legend.spacing.x : NULL
## $ legend.spacing.y : NULL
## $ legend.key : list()
## ..- attr(*, "class")= chr [1:2] "element_blank" "element"
## $ legend.key.size : 'simpleUnit' num 1.2lines
## ..- attr(*, "unit")= int 3
## $ legend.key.height : NULL
## $ legend.key.width : NULL
## $ legend.key.spacing : 'simpleUnit' num 5.5points
## ..- attr(*, "unit")= int 8
## $ legend.key.spacing.x : NULL
## $ legend.key.spacing.y : NULL
## $ legend.frame : NULL
## $ legend.ticks : NULL
## $ legend.ticks.length : 'rel' num 0.2
## $ legend.axis.line : NULL
## $ legend.text :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : 'rel' num 0.8
## ..$ hjust : NULL
## ..$ vjust : NULL
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : NULL
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ legend.text.position : NULL
## $ legend.title :List of 11
## ..$ family : NULL
## ..$ face : NULL
## ..$ colour : NULL
## ..$ size : NULL
## ..$ hjust : num 0
## ..$ vjust : NULL
## ..$ angle : NULL
## ..$ lineheight : NULL
## ..$ margin : NULL
## ..$ debug : NULL
## ..$ inherit.blank: logi TRUE
## ..- attr(*, "class")= chr [1:2] "element_text" "element"
## $ legend.title.position : NULL
## $ legend.position : chr "right"
## $ legend.position.inside : NULL
## $ legend.direction : NULL
## $ legend.byrow : NULL
## $ legend.justification : chr "center"
## $ legend.justification.top : NULL
## $ legend.justification.bottom : NULL
## $ legend.justification.left : NULL
## $ legend.justification.right : NULL
## $ legend.justification.inside : NULL
## $ legend.location : NULL
## $ legend.box : NULL
## $ legend.box.just : NULL
## $ legend.box.margin : 'margin' num [1:4] 0cm 0cm 0cm 0cm
## ..- attr(*, "unit")= int 1
## $ legend.box.background : list()
## ..- attr(*, "class")= chr [1:2] "element_blank" "element"
## $ legend.box.spacing : 'simpleUnit' num 11points
## ..- attr(*, "unit")= int 8
## [list output truncated]
## - attr(*, "class")= chr [1:2] "theme" "gg"
## - attr(*, "complete")= logi TRUE
## - attr(*, "validate")= logi TRUE
ggplot(df_cluster2, aes(x = Rata_Harga,
y = cluster,
color = Cluster_PAM)) +
geom_point(size = 3) +
labs(title = "K-Medoids (PAM) Clustering Berdasarkan Harga Beras 2024",
x = "Rata-rata Harga Beras",
y = "Cluster (PAM)") +
theme_minimal()
range_pam <- df_cluster2 %>%
group_by(Cluster_PAM) %>%
summarise(
Min_Harga = min(Rata_Harga, na.rm = TRUE),
Max_Harga = max(Rata_Harga, na.rm = TRUE),
Avg_Harga = mean(Rata_Harga, na.rm = TRUE)
)
range_pam
## # A tibble: 4 × 4
## Cluster_PAM Min_Harga Max_Harga Avg_Harga
## <fct> <dbl> <dbl> <dbl>
## 1 1 13470. 14153. 13909.
## 2 2 14410. 15314. 14797.
## 3 3 15836. 16953. 16348.
## 4 4 20901. 20901. 20901.
Cluster 1 (Merah) menunjukkan cluster dengan harga rendah, cluster 2 (Hijau) menunjukkan cluster dengan harga menengah, cluster 3 (Biru) menunjukkan harga cukup tinggi, dan cluster 4 (Ungu) menunjukkan harga sangat tinggi.
df_cluster2$Cluster_Kmeans <- km_model1$cluster
df_cluster2$Cluster_PAM <- pam_model$cluster
print(df_cluster2)
## # A tibble: 34 × 5
## NamaProv Rata_Harga cluster Cluster_PAM Cluster_Kmeans
## <chr> <dbl> <fct> <int> <int>
## 1 Aceh 13975. 1 1 1
## 2 Bali 14765. 4 2 4
## 3 Banten 13979. 1 1 1
## 4 Bengkulu 14410. 4 2 4
## 5 DI Yogyakarta 13995. 1 1 1
## 6 DKI Jakarta 14952. 4 2 4
## 7 Gorontalo 14631 4 2 4
## 8 Jambi 13972. 1 1 1
## 9 Jawa Barat 14072. 1 1 1
## 10 Jawa Tengah 14153. 1 1 1
## # ℹ 24 more rows
Masing-masing dari K-Means dan K-Medoids membagi cluster menjadi 4 dengan kategori, rendah (1), menengah (4), cukup tinggi (3), dan sangat tinggi (2). Pada kedua metode tersebut, terdapat beberapa provinsi yang berada di 2 cluster berbeda, contohnya adalah Kalimantan Selatan yang berada dicluster 4 pada K-Means dan berada di cluster 2 pada K-medoids. Hal tersebut dikarenakan perbedaan labeling pada kedua cluster