`

Mengambil dataset “starwars”

# Load library
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.2
## 
## 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(moments)

# Menghapus nilai NA dari dataset starwars
data_sw <- starwars %>% na.omit()

# Memastikan kolom height dan mass adalah numerik
data_sw <- data_sw %>%
  mutate(height = as.numeric(height),
         mass = as.numeric(mass))

# Memilih kolom height dan mass
data_height <- data_sw %>% pull(height)  # Mengambil sebagai vektor
data_mass <- data_sw %>% pull(mass)      # Mengambil sebagai vektor

head (data_height); # menampilkan beberapa data Height
## [1] 172 202 150 178 165 183
head (data_height); # menampilkan beberapa data mass
## [1] 172 202 150 178 165 183

1. Melakukan Eksplorasi pada data yang sudah didapatkan

a) eksplorasi dengan menentukan 5 nilai

summary_height <- summary(data_height)  # Lima nilai ringkasan Height
summary_mass <- summary(data_mass)      # Lima nilai ringkasan Mass

print("Lima Nilai Ringkasan untuk Height:")  # Menampilkan hasil
## [1] "Lima Nilai Ringkasan untuk Height:"
print(summary_height)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    88.0   172.0   180.0   178.7   188.0   228.0
print("Lima Nilai Ringkasan untuk Mass:")    # Menampilkan hasil
## [1] "Lima Nilai Ringkasan untuk Mass:"
print(summary_mass)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   20.00   75.00   79.00   77.77   83.00  136.00

Lima nilai ringkasan untuk peubah Height menunjukkan bahwa tinggi badan dalam dataset berkisar antara 88 hingga 228, dengan nilai median 180, yang berarti setengah dari data memiliki tinggi di bawah 180 dan setengah lainnya di atasnya. Rentang interkuartil (IQR) dari 172 hingga 188 menunjukkan bahwa sebagian besar individu memiliki tinggi dalam kisaran ini.

Sementara itu, untuk peubah Mass, berat badan berkisar antara 20 hingga 136, dengan median 79, yang menunjukkan distribusi data relatif seimbang. Rentang interkuartil untuk Mass adalah 75 hingga 83, yang menunjukkan bahwa sebagian besar individu memiliki berat badan dalam kisaran ini.

b) eksplorasi dengan menentukan nilai skewness dan kurtosis

# Menghitung skewness Height dan Mass
skewness_height <- skewness(data_height, na.rm = TRUE)
skewness_mass <- skewness(data_mass, na.rm = TRUE)

# Menghitung kurtosis Height dan Mass
kurtosis_height <- kurtosis(data_height, na.rm = TRUE)
kurtosis_mass <- kurtosis(data_mass, na.rm = TRUE)

# Menampilkan hasil
print(paste("Skewness Height:", skewness_height))
## [1] "Skewness Height: -2.01402050163969"
print(paste("Skewness Mass:", skewness_mass))
## [1] "Skewness Mass: 0.179425163090054"
print(paste("Kurtosis Height:", kurtosis_height))
## [1] "Kurtosis Height: 10.9963035925878"
print(paste("Kurtosis Mass:", kurtosis_mass))
## [1] "Kurtosis Mass: 4.12447380075675"

Nilai skewness untuk height sebesar -2.014021 menunjukkan bahwa distribusi tinggi badan cenderung miring ke kiri (negatively skewed), yang berarti lebih banyak individu memiliki tinggi di atas rata-rata, tetapi ada beberapa individu dengan tinggi yang jauh lebih kecil. Sebaliknya, nilai skewness mass sebesar 0.1794252 mendekati nol, yang mengindikasikan distribusi berat badan relatif simetris.

Nilai kurtosis height yang cukup tinggi (10.9963) menunjukkan bahwa distribusinya memiliki puncak yang lebih tajam dan ekor yang lebih panjang, menandakan adanya banyak outlier atau nilai ekstrem dalam data. Sementara itu, kurtosis mass sebesar 4.124474 menunjukkan distribusi yang masih lebih leptokurtic (berpuncak tajam) dibanding distribusi normal, meskipun tidak seekstrem height.

2 Mencari Nilai Pencilan

a) mencari pencilan dengan boxplot

# Boxplot untuk Height
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.2
ggplot(data_sw, aes(y = height)) + 
  geom_boxplot(fill = "lightblue", color = "red", outlier.colour = "black") +  # Menandai outlier
  labs(title = "Boxplot of Height", y = "Height (cm)") +
  theme_minimal()  # agar lebih rapi

# Boxplot untuk Mass
ggplot(data_sw, aes(y = mass)) + 
  geom_boxplot(fill = "lightgreen", color = "black", outlier.colour = "red") +  # Menandai outlier
  labs(title = "Boxplot of Mass", y = "Mass (kg)") +
  theme_minimal()  # agar lebih rapi

Boxplot untuk peubah height menunjukkan adanya outlier, ditandai dengan titik hitam di luar Pagar, yang mengindikasikan adanya orang dengan tinggi badan ekstrem, baik yang sangat kecil maupun sangat besar.

Boxplot untuk peubah mass juga menunjukkan adanya outlier, ditandai dengan titik merah di luar Pagar, yang mengindikasikan adanya orang dengan berat badan ekstrem. Outlier yang terdeteksi pada data Mass lebih banyak daripada pada data Height

b) mencari pencilan dengan histogram

library(ggplot2)  # Memasukkan library ggplot2

# Histogram untuk Height
ggplot(data_sw, aes(x = height)) + 
  geom_histogram(binwidth = 5, fill = "blue", color = "black", alpha = 0.5) +
  labs(title = "Histogram of Height", x = "Height (cm)", y = "Frequency")

# Histogram untuk Height
ggplot(data_sw, aes(x = mass)) + 
  geom_histogram(binwidth = 5, fill = "green", color = "black", alpha = 0.5) +
  labs(title = "Histogram of Mass", x = "Mass (kg)", y = "Frequency")

Histogram height menunjukkan bahwa distribusi tinggi badan dalam dataset cenderung memiliki konsentrasi nilai di sekitar rentang 160–200 cm, dengan beberapa nilai ekstrem di bagian bawah dan atas yang dapat dianggap sebagai pencilan. Distribusi ini terlihat sedikit miring ke kiri (negatively skewed), sebagaimana didukung oleh nilai skewness negatif yang diperoleh sebelumnya.

Histogram mass menunjukkan bahwa distribusi berat badan dalam dataset cenderung tidak merata, dengan satu puncak dominan di sekitar nilai tertentu yang memiliki frekuensi tertinggi. Distribusi ini menunjukkan adanya konsentrasi berat badan pada rentang tertentu, sementara nilai lainnya lebih tersebar dengan frekuensi yang lebih rendah.

c) mencari pencilan dengan uji IQR

# ----- Metode 1: Uji IQR -----
detect_outliers_iqr <- function(var) {
  Q1 <- quantile(var, 0.25, na.rm = TRUE)
  Q3 <- quantile(var, 0.75, na.rm = TRUE)
  IQR_value <- Q3 - Q1
  lower_bound <- Q1 - 1.5 * IQR_value
  upper_bound <- Q3 + 1.5 * IQR_value
  
  return(var[var < lower_bound | var > upper_bound])
}

outliers_height_iqr <- detect_outliers_iqr(data_height)
outliers_mass_iqr <- detect_outliers_iqr(data_mass)

print("Outliers berdasarkan IQR:")
## [1] "Outliers berdasarkan IQR:"
print(outliers_height_iqr)
## [1] 228  88
print(outliers_mass_iqr)
##  [1] 136.0  49.0 120.0 112.0 113.0  20.0  45.0  55.0  56.2  50.0

Berdasarkan hasil analisis menggunakan metode Interquartile Range (IQR), ditemukan bahwa terdapat pencilan pada variabel height dengan nilai 228 dan 88, serta pada variabel mass dengan nilai 136.0, 49.0, 120.0, 112.0, 113.0, 20.0, 45.0, 55.0, 56.2, dan 50.0. Nilai-nilai ini berada di luar batas normal yang ditentukan oleh IQR, sehingga dapat dianggap sebagai data yang menyimpang dari pola umum distribusi.

3 Menentukan Rata-Rata Kekar

a) dengan Winsorized Mean

# Load packages
library(DescTools)
## Warning: package 'DescTools' was built under R version 4.4.3
library(robustHD)
## Warning: package 'robustHD' was built under R version 4.4.3
## Loading required package: perry
## Warning: package 'perry' was built under R version 4.4.3
## Loading required package: parallel
## Loading required package: robustbase
## Warning: package 'robustbase' was built under R version 4.4.3
# Melakukan Winsorizing ari data Height dan Mass dengan batas persentil 15% dan 85%
winsorized_h <- winsorize(data_height, probs = c(0.15, 0.85))
winsorized_m <- winsorize(data_mass, probs = c(0.15, 0.85))

# Menghitung mean setelah Winsorizing
mean_height_winsor <- mean(winsorized_h, na.rm = TRUE)
mean_mass_winsor <- mean(winsorized_m, na.rm = TRUE)

# Menampilkan hasil
print(paste("Winsorized Mean Height:", mean_height_winsor))
## [1] "Winsorized Mean Height: 180.388910344828"
print(paste("Winsorized Mean Mass:", mean_mass_winsor))
## [1] "Winsorized Mean Mass: 78.1592275862069"

b) dengan Trimmed Mean

# Menghitung Trimmed Mean dari data Height dan Mass (memotong 15% dari bawah dan atas)
trimmed_mean_height <- mean(data_sw$height, trim = 0.15, na.rm = TRUE)
trimmed_mean_mass <- mean(data_sw$mass, trim = 0.15, na.rm = TRUE)

# Menampilkan hasil
print(paste("Trimmed Mean Height:", trimmed_mean_height))
## [1] "Trimmed Mean Height: 180.380952380952"
print(paste("Trimmed Mean Mass:", trimmed_mean_mass))
## [1] "Trimmed Mean Mass: 76.6857142857143"

Untuk Height akan lebih bagus menggunakan Winsorized Mean karena ini mempertahankan keseluruhan data tetapi tetap mengurangi pengaruh pencilan, kalaupun menggunakan trimmed juga tidak masalah karena pencilannya sedikit dan nilai trimmed mean dan winsorized mean tidak beda jauh. Sedangkan mass akan lebih baik menggunakan Trimmed Mean karena Mass banyak memiliki pencilan ekstrem.

4 Menentukan apakah amatan baru pencilan atau bukan

data_height <- rbind(data_height, data.frame(height = 210))  # memasukkan amatan height baru
## Warning in rbind(deparse.level, ...): number of columns of result, 1, is not a
## multiple of vector length 29 of arg 1
data_mass <- rbind(data_mass, data.frame(mass = 100))  #memasukkan amatan mass baru
## Warning in rbind(deparse.level, ...): number of columns of result, 1, is not a
## multiple of vector length 29 of arg 1
print(data_height); #menampilan data Height yang telah ditambah amatan baru
##   height
## 1    172
## 2    210
print(data_mass);   #menampilan data Mass yang telah ditambah amatan baru
##   mass
## 1   77
## 2  100

cek pencilan dengan Sequentials Fence

library(dplyr)

# Fungsi Sequential Fences untuk menangani pencilan
sequential_fences <- function(data) {
  Q1 <- quantile(data, 0.25, na.rm = TRUE)  #menentukan kuartil pertama untuk sequential fences
  Q3 <- quantile(data, 0.75, na.rm = TRUE)  #menentukan kuartil ketiga untuk sequential fences
  IQR_value <- Q3 - Q1   #menentukan jangkauan antar kuartil untuk sequential fences
  
  k <- 1.5  # Faktor awal
  lower_fence <- Q1 - (k * IQR_value)  #Menghitung batas bawah (lower_fence) dikalikan faktor k.
  upper_fence <- Q3 + (k * IQR_value)  #Menghitung batas atas (upper_fence) dikalikan faktor k.

  outliers <- data[data < lower_fence | data > upper_fence] # menentukan oulier data
  data <- data[data >= lower_fence & data <= upper_fence]

  while (length(outliers) > 0) {
    Q1 <- quantile(data, 0.25, na.rm = TRUE)  # menentukan kuartil 1
    Q3 <- quantile(data, 0.75, na.rm = TRUE)  # menentukan kuartil 3
    IQR_value <- Q3 - Q1        # menentukan jangkauan antar kuartil
    
    k <- k + 0.5  # Meningkatkan faktor
    
    lower_fence <- Q1 - (k * IQR_value)  # menghitung pagar bawah
    upper_fence <- Q3 + (k * IQR_value)  # menghitung pagar atas
    
    outliers <- data[data < lower_fence | data > upper_fence]  
    data <- data[data >= lower_fence & data <= upper_fence]  
  }
  
  return(data)
}

# data asli untuk perbandingan
awal_height <- data_height
awal_mass <- data_mass

# Menangani pencilan dengan metode Sequential Fences
sf_height <- sequential_fences(awal_height)
sf_mass <- sequential_fences(awal_mass)

# Visualisasi sebelum & sesudah
par(mfrow = c(1,2))  
boxplot(awal_height, main = "Boxplot Height (Original)")
boxplot(sf_height, main = "Boxplot Height (Sequential Fences)")

par(mfrow = c(1,2))  
boxplot(awal_mass, main = "Boxplot Mass (Original)")
boxplot(sf_mass, main = "Boxplot Mass (Sequential Fences)")

Berdasarkan boxplot sebelum dan sesudah Sequential Fences, terlihat bahwa terdapat data yang awalnya terdeteksi sebagai pencilan pada boxplot asli (Original), tetapi kemudian tidak lagi dianggap sebagai pencilan setelah proses iteratif yang memperluas batas deteksi pencilan. Saat ditambahkan amatan baru dengan height = 210 masih berada dalam pagar, sehingga tidak dianggap pencilan.

Berdasarkan boxplot sebelum dan sesudah Sequential Fences, terlihat bahwa terdapat data yang awalnya terdeteksi sebagai pencilan pada boxplot asli (Original), tetapi kemudian tidak lagi dianggap sebagai pencilan setelah proses iteratif yang memperluas batas deteksi pencilan. Namun, untuk mass 100, berdasarkan boxplot massa (Mass), amatan tersebut berada di luar pagar pada boxplot Sequential Fences, sehingga masih dapat dikategorikan sebagai pencilan.