# Memuat library dplyr untuk manipulasi data
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
# Memuat library ggplot2 untuk visualisasi data
library(ggplot2)
# Memuat dataset starwars yang sudah tersedia dalam paket dplyr
data(starwars)
# Menghapus baris yang mengandung nilai NA (missing values) dari dataset starwars
starwars_data <- starwars %>%
na.omit()
# Menyimpan kolom 'height' dari starwars_data ke dalam variabel height_data
height_data <- starwars_data$height
# Menyimpan kolom 'mass' dari starwars_data ke dalam variabel mass_data
mass_data <- starwars_data$mass
# Membuat dataframe baru bernama data1 yang berisi kolom 'height' dan 'mass' dari starwars_data
data1 <- data.frame(height = starwars_data$height, mass = starwars_data$mass)
str(height_data)
## int [1:29] 172 202 150 178 165 183 182 188 228 180 ...
str(mass_data)
## num [1:29] 77 136 49 120 75 84 77 84 112 80 ...
summary(height_data)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 88.0 172.0 180.0 178.7 188.0 228.0
summary(mass_data)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 20.00 75.00 79.00 77.77 83.00 136.00
ggplot(starwars_data, aes(x = height)) + # Menggunakan data 'starwars_data' dan menentukan kolom 'height' untuk sumbu X
geom_histogram(bins = 15, fill = "blue", color = "black") + # Membuat histogram dengan 15 bin, warna isian biru, dan warna batas hitam
ggtitle("Distribusi Height pada Dataset Starwars") + # Memberikan judul pada plot
xlab("Height") + # Menambahkan label pada sumbu X
ylab("Frekuensi") # Menambahkan label pada sumbu Y
ggplot(starwars_data, aes(x = mass)) + # Menggunakan data 'starwars_data' dan menentukan kolom 'mass' untuk sumbu X
geom_histogram(bins = 15, fill = "green", color = "black") + # Membuat histogram dengan 15 bin, warna isian hijau, dan warna batas hitam
ggtitle("Distribusi Mass pada Dataset Starwars") + # Memberikan judul pada plot
xlab("Mass") + # Menambahkan label pada sumbu X
ylab("Frekuensi") # Menambahkan label pada sumbu Y
hist(height_data, # Menggunakan data tinggi karakter
main="Distribusi Height", # Menambahkan judul histogram
xlab="Height", # Label untuk sumbu X
col="orange", # Warna batang histogram
border="black", # Warna batas setiap batang histogram
breaks=20) # Membagi histogram menjadi 20 interval (bin)
hist(mass_data, # Menggunakan data massa karakter
main="Distribusi Mass", # Menambahkan judul histogram
xlab="Mass", # Label untuk sumbu X
col="yellow", # Warna batang histogram
border="black", # Warna batas setiap batang histogram
breaks=20) # Membagi histogram menjadi 20 interval (bin)
### Boxplot
boxplot(height_data, # Menggunakan data tinggi karakter
main="Boxplot Height", # Menambahkan judul boxplot
ylab="Height", # Label untuk sumbu Y
col="lightblue", # Warna boxplot
border="black") # Warna batas boxplot
boxplot(mass_data, # Menggunakan data massa karakter
main="Boxplot Mass", # Menambahkan judul boxplot
ylab="Mass", # Label untuk sumbu Y
col="lightgreen", # Warna boxplot
border="black") # Warna batas boxplot
### Scatterplot
plot(height_data, mass_data, # Menggunakan data tinggi sebagai X dan massa sebagai Y
main="Scatterplot: Height vs Mass", # Menambahkan judul scatterplot
xlab="Height", # Label untuk sumbu X
ylab="Mass", # Label untuk sumbu Y
pch=19, # Tipe titik (19 = bulatan penuh)
col="darkblue") # Warna titik scatterplot
### Mencari Pencilan
IQR.hwy = IQR(height_data) # Menghitung Interquartile Range (IQR) dari height_data
Q1.height = quantile(height_data, 0.25) # Kuartil pertama (Q1)
Q3.height = quantile(height_data, 0.75) # Kuartil ketiga (Q3)
batas.bawah = Q1.height - 1.5*IQR.hwy # Menentukan batas bawah pencilan
batas.atas = Q3.height + 1.5*IQR.hwy # Menentukan batas atas pencilan
nilai_pencilan = height_data[height_data < batas.bawah | height_data > batas.atas] # Menentukan nilai yang berada di luar batas bawah dan atas (outlier)
nilai_pencilan # Menampilkan nilai pencilan
## [1] 228 88
lokasi_pencilan_pada_urut_ke = which(height_data < batas.bawah | height_data > batas.atas)# Mencari indeks dari nilai yang merupakan pencilan
lokasi_pencilan_pada_urut_ke # Menampilkan indeks dari pencilan
## [1] 9 18
boxplot.stats(height_data)$out # Menampilkan nilai outlier langsung dari fungsi boxplot
## [1] 228 88
pencilan = boxplot.stats(height_data)$out # Menyimpan nilai pencilan
lokasi_pencilan = which(height_data %in% c(pencilan)) # Mencari lokasi indeks dari pencilan
lokasi_pencilan # Menampilkan indeks pencilan
## [1] 9 18
boxplot(height_data, # Membuat boxplot untuk tinggi
xlab = "height", # Label sumbu X
ylab = "Value", # Label sumbu Y
main = "Boxplot Height" # Judul boxplot
)
mtext(paste("Pencilan: ", paste(pencilan, collapse = ", "))) # Menampilkan teks di bawah plot dengan nilai pencilan yang ditemukan
#### Cara 1 (Mass) - Tukey’s Fence
IQR.mass = IQR(mass_data)
Q1.mass = quantile(mass_data, 0.25)
Q3.mass = quantile(mass_data, 0.75)
batas.bawah = Q1.mass - 1.5*IQR.mass
batas.atas = Q3.mass + 1.5*IQR.mass
nilai_pencilan_mass = mass_data[mass_data < batas.bawah | mass_data > batas.atas]
nilai_pencilan_mass
## [1] 136.0 49.0 120.0 112.0 113.0 20.0 45.0 55.0 56.2 50.0
lokasi_pencilan_mass_pada_urut_ke = which(mass_data < batas.bawah | mass_data > batas.atas)
lokasi_pencilan_mass_pada_urut_ke
## [1] 2 3 4 9 14 18 19 22 26 27
boxplot.stats(mass_data)$out
## [1] 136.0 49.0 120.0 112.0 113.0 20.0 45.0 55.0 56.2 50.0
pencilann = boxplot.stats(mass_data)$out
lokasi_pencilan_mass = which(mass_data %in% c(pencilann))
lokasi_pencilan_mass
## [1] 2 3 4 9 14 18 19 22 26 27
boxplot(mass_data,
xlab = "mass",
ylab = "Value",
main = "Boxplot Mass"
)
mtext(paste("Pencilan: ", paste(pencilann, collapse = ", ")))
Namun, jika kita menggunakan Winsorized Mean, kita tidak membuang data ekstrim, melainkan menggantinya dengan nilai batas terdekat dalam distribusi. Meskipun ini juga berguna untuk menangani pencilan, Trimmed Mean lebih cocok pada kasus ini karena pencilan pada data Mass cukup jauh, serta pencilannya juga banyak, sehingga mengurangi data lebih efektif daripada menggantinya.
Sementara itu, untuk data Height, pencilannya tidak begitu ekstrem. Dalam kasus ini, menggunakan Winsorized Mean bisa lebih tepat, karena pencilan tidak terlalu besar dan menggantinya dengan batas terdekat bisa memberikan estimasi yang lebih stabil tanpa menghilangkan data.
rataan.heightbiasa = mean(height_data)
rataan.heightterpangkas = mean(height_data, trim = 0.15)
cat("Rataan height Biasa: ", rataan.heightbiasa, "\n")
## Rataan height Biasa: 178.6552
cat("Rataan height Terpangkas : ", rataan.heightterpangkas)
## Rataan height Terpangkas : 180.381
library(datawizard)
## Warning: package 'datawizard' was built under R version 4.4.3
cat("Sebelum : ",mass_data)
## Sebelum : 77 136 49 120 75 84 77 84 112 80 77 75 78.2 113 79 79 83 20 45 66 80 55 84 82 80 56.2 50 80 79
win.mass_data=winsorize(
mass_data,
threshold = 0.15,
method = "percentile",
robust = FALSE,
verbose = TRUE)
cat("\nSesudah : ",win.mass_data)
##
## Sesudah : 77 84 55 84 75 84 77 84 84 80 77 75 78.2 84 79 79 83 55 55 66 80 55 84 82 80 56.2 55 80 79
cat("\nWinsorized Mean dari mass_data : ",mean(winsorize(win.mass_data)))
##
## Winsorized Mean dari mass_data : 74.91034
data <- rbind(data1, data.frame(height = 210, mass = 100))
data
## height mass
## 1 172 77.0
## 2 202 136.0
## 3 150 49.0
## 4 178 120.0
## 5 165 75.0
## 6 183 84.0
## 7 182 77.0
## 8 188 84.0
## 9 228 112.0
## 10 180 80.0
## 11 170 77.0
## 12 170 75.0
## 13 183 78.2
## 14 190 113.0
## 15 177 79.0
## 16 175 79.0
## 17 180 83.0
## 18 88 20.0
## 19 185 45.0
## 20 196 66.0
## 21 175 80.0
## 22 178 55.0
## 23 188 84.0
## 24 198 82.0
## 25 188 80.0
## 26 170 56.2
## 27 166 50.0
## 28 193 80.0
## 29 183 79.0
## 30 210 100.0
iqr_height <- IQR(data$height)
iqr_mass <- IQR(data$mass)
q1_height <- quantile(data$height, 0.25)
q3_height <- quantile(data$height, 0.75)
q1_mass <- quantile(data$mass, 0.25)
q3_mass <- quantile(data$mass, 0.75)
lower_bound_height <- q1_height - 1.5 * iqr_height
upper_bound_height <- q3_height + 1.5 * iqr_height
lower_bound_mass <- q1_mass - 1.5 * iqr_mass
upper_bound_mass <- q3_mass + 1.5 * iqr_mass
height_outlier <- 210 < lower_bound_height | 210 > upper_bound_height
mass_outlier <- 100 < lower_bound_mass | 100 > upper_bound_mass
cat("210 termasuk pencilan pada height? ", height_outlier , "\n")
## 210 termasuk pencilan pada height? FALSE
cat("100 termasuk pencilan pada mass? ", mass_outlier, "\n")
## 100 termasuk pencilan pada mass? TRUE