R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.

When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

# === LIBRARY ===
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(caret)
## Loading required package: lattice
## 
## Attaching package: 'caret'
## 
## The following object is masked from 'package:purrr':
## 
##     lift
library(e1071)
library(MASS)
## 
## Attaching package: 'MASS'
## 
## The following object is masked from 'package:dplyr':
## 
##     select
library(caTools)
library(psych)
## 
## Attaching package: 'psych'
## 
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(lmtest)
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## 
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(corrplot)
## corrplot 0.95 loaded
# === LOAD DATA ===
data <- read.csv("students_dropout_academic_success.csv", header = TRUE)
colnames(data) <- make.names(colnames(data))  # bersihkan nama kolom

# === PREPROCESSING DATA ===
# Cek nilai yang hilang (missing values)
sum(is.na(data))
## [1] 0
# Mengganti nilai yang hilang dengan median untuk kolom numerik
data[] <- lapply(data, function(x) ifelse(is.numeric(x), 
                                           ifelse(is.na(x), median(x, na.rm = TRUE), x), x))

# Pastikan target adalah variabel faktor
data$target <- as.factor(data$target)

# === STATISTIK DESKRIPTIF ===
str(data)
## 'data.frame':    4424 obs. of  37 variables:
##  $ Marital.Status                                : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Application.mode                              : int  17 17 17 17 17 17 17 17 17 17 ...
##  $ Application.order                             : int  5 5 5 5 5 5 5 5 5 5 ...
##  $ Course                                        : int  171 171 171 171 171 171 171 171 171 171 ...
##  $ Daytime.evening.attendance                    : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Previous.qualification                        : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Previous.qualification..grade.                : num  122 122 122 122 122 122 122 122 122 122 ...
##  $ Nacionality                                   : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Mother.s.qualification                        : int  19 19 19 19 19 19 19 19 19 19 ...
##  $ Father.s.qualification                        : int  12 12 12 12 12 12 12 12 12 12 ...
##  $ Mother.s.occupation                           : int  5 5 5 5 5 5 5 5 5 5 ...
##  $ Father.s.occupation                           : int  9 9 9 9 9 9 9 9 9 9 ...
##  $ Admission.grade                               : num  127 127 127 127 127 ...
##  $ Displaced                                     : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Educational.special.needs                     : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Debtor                                        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Tuition.fees.up.to.date                       : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Gender                                        : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Scholarship.holder                            : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Age.at.enrollment                             : int  20 20 20 20 20 20 20 20 20 20 ...
##  $ International                                 : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.1st.sem..credited.           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.1st.sem..enrolled.           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.1st.sem..evaluations.        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.1st.sem..approved.           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.1st.sem..grade.              : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.1st.sem..without.evaluations.: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.2nd.sem..credited.           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.2nd.sem..enrolled.           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.2nd.sem..evaluations.        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.2nd.sem..approved.           : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.2nd.sem..grade.              : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ Curricular.units.2nd.sem..without.evaluations.: int  0 0 0 0 0 0 0 0 0 0 ...
##  $ Unemployment.rate                             : num  10.8 10.8 10.8 10.8 10.8 10.8 10.8 10.8 10.8 10.8 ...
##  $ Inflation.rate                                : num  1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.4 1.4 ...
##  $ GDP                                           : num  1.74 1.74 1.74 1.74 1.74 1.74 1.74 1.74 1.74 1.74 ...
##  $ target                                        : Factor w/ 1 level "Dropout": 1 1 1 1 1 1 1 1 1 1 ...
summary(data)
##  Marital.Status Application.mode Application.order     Course   
##  Min.   :1      Min.   :17       Min.   :5         Min.   :171  
##  1st Qu.:1      1st Qu.:17       1st Qu.:5         1st Qu.:171  
##  Median :1      Median :17       Median :5         Median :171  
##  Mean   :1      Mean   :17       Mean   :5         Mean   :171  
##  3rd Qu.:1      3rd Qu.:17       3rd Qu.:5         3rd Qu.:171  
##  Max.   :1      Max.   :17       Max.   :5         Max.   :171  
##  Daytime.evening.attendance Previous.qualification
##  Min.   :1                  Min.   :1             
##  1st Qu.:1                  1st Qu.:1             
##  Median :1                  Median :1             
##  Mean   :1                  Mean   :1             
##  3rd Qu.:1                  3rd Qu.:1             
##  Max.   :1                  Max.   :1             
##  Previous.qualification..grade.  Nacionality Mother.s.qualification
##  Min.   :122                    Min.   :1    Min.   :19            
##  1st Qu.:122                    1st Qu.:1    1st Qu.:19            
##  Median :122                    Median :1    Median :19            
##  Mean   :122                    Mean   :1    Mean   :19            
##  3rd Qu.:122                    3rd Qu.:1    3rd Qu.:19            
##  Max.   :122                    Max.   :1    Max.   :19            
##  Father.s.qualification Mother.s.occupation Father.s.occupation Admission.grade
##  Min.   :12             Min.   :5           Min.   :9           Min.   :127.3  
##  1st Qu.:12             1st Qu.:5           1st Qu.:9           1st Qu.:127.3  
##  Median :12             Median :5           Median :9           Median :127.3  
##  Mean   :12             Mean   :5           Mean   :9           Mean   :127.3  
##  3rd Qu.:12             3rd Qu.:5           3rd Qu.:9           3rd Qu.:127.3  
##  Max.   :12             Max.   :5           Max.   :9           Max.   :127.3  
##    Displaced Educational.special.needs     Debtor  Tuition.fees.up.to.date
##  Min.   :1   Min.   :0                 Min.   :0   Min.   :1              
##  1st Qu.:1   1st Qu.:0                 1st Qu.:0   1st Qu.:1              
##  Median :1   Median :0                 Median :0   Median :1              
##  Mean   :1   Mean   :0                 Mean   :0   Mean   :1              
##  3rd Qu.:1   3rd Qu.:0                 3rd Qu.:0   3rd Qu.:1              
##  Max.   :1   Max.   :0                 Max.   :0   Max.   :1              
##      Gender  Scholarship.holder Age.at.enrollment International
##  Min.   :1   Min.   :0          Min.   :20        Min.   :0    
##  1st Qu.:1   1st Qu.:0          1st Qu.:20        1st Qu.:0    
##  Median :1   Median :0          Median :20        Median :0    
##  Mean   :1   Mean   :0          Mean   :20        Mean   :0    
##  3rd Qu.:1   3rd Qu.:0          3rd Qu.:20        3rd Qu.:0    
##  Max.   :1   Max.   :0          Max.   :20        Max.   :0    
##  Curricular.units.1st.sem..credited. Curricular.units.1st.sem..enrolled.
##  Min.   :0                           Min.   :0                          
##  1st Qu.:0                           1st Qu.:0                          
##  Median :0                           Median :0                          
##  Mean   :0                           Mean   :0                          
##  3rd Qu.:0                           3rd Qu.:0                          
##  Max.   :0                           Max.   :0                          
##  Curricular.units.1st.sem..evaluations. Curricular.units.1st.sem..approved.
##  Min.   :0                              Min.   :0                          
##  1st Qu.:0                              1st Qu.:0                          
##  Median :0                              Median :0                          
##  Mean   :0                              Mean   :0                          
##  3rd Qu.:0                              3rd Qu.:0                          
##  Max.   :0                              Max.   :0                          
##  Curricular.units.1st.sem..grade.
##  Min.   :0                       
##  1st Qu.:0                       
##  Median :0                       
##  Mean   :0                       
##  3rd Qu.:0                       
##  Max.   :0                       
##  Curricular.units.1st.sem..without.evaluations.
##  Min.   :0                                     
##  1st Qu.:0                                     
##  Median :0                                     
##  Mean   :0                                     
##  3rd Qu.:0                                     
##  Max.   :0                                     
##  Curricular.units.2nd.sem..credited. Curricular.units.2nd.sem..enrolled.
##  Min.   :0                           Min.   :0                          
##  1st Qu.:0                           1st Qu.:0                          
##  Median :0                           Median :0                          
##  Mean   :0                           Mean   :0                          
##  3rd Qu.:0                           3rd Qu.:0                          
##  Max.   :0                           Max.   :0                          
##  Curricular.units.2nd.sem..evaluations. Curricular.units.2nd.sem..approved.
##  Min.   :0                              Min.   :0                          
##  1st Qu.:0                              1st Qu.:0                          
##  Median :0                              Median :0                          
##  Mean   :0                              Mean   :0                          
##  3rd Qu.:0                              3rd Qu.:0                          
##  Max.   :0                              Max.   :0                          
##  Curricular.units.2nd.sem..grade.
##  Min.   :0                       
##  1st Qu.:0                       
##  Median :0                       
##  Mean   :0                       
##  3rd Qu.:0                       
##  Max.   :0                       
##  Curricular.units.2nd.sem..without.evaluations. Unemployment.rate
##  Min.   :0                                      Min.   :10.8     
##  1st Qu.:0                                      1st Qu.:10.8     
##  Median :0                                      Median :10.8     
##  Mean   :0                                      Mean   :10.8     
##  3rd Qu.:0                                      3rd Qu.:10.8     
##  Max.   :0                                      Max.   :10.8     
##  Inflation.rate      GDP           target    
##  Min.   :1.4    Min.   :1.74   Dropout:4424  
##  1st Qu.:1.4    1st Qu.:1.74                 
##  Median :1.4    Median :1.74                 
##  Mean   :1.4    Mean   :1.74                 
##  3rd Qu.:1.4    3rd Qu.:1.74                 
##  Max.   :1.4    Max.   :1.74
describe(data[, sapply(data, is.numeric)])
##                                                vars    n   mean sd median
## Marital.Status                                    1 4424   1.00  0   1.00
## Application.mode                                  2 4424  17.00  0  17.00
## Application.order                                 3 4424   5.00  0   5.00
## Course                                            4 4424 171.00  0 171.00
## Daytime.evening.attendance                        5 4424   1.00  0   1.00
## Previous.qualification                            6 4424   1.00  0   1.00
## Previous.qualification..grade.                    7 4424 122.00  0 122.00
## Nacionality                                       8 4424   1.00  0   1.00
## Mother.s.qualification                            9 4424  19.00  0  19.00
## Father.s.qualification                           10 4424  12.00  0  12.00
## Mother.s.occupation                              11 4424   5.00  0   5.00
## Father.s.occupation                              12 4424   9.00  0   9.00
## Admission.grade                                  13 4424 127.30  0 127.30
## Displaced                                        14 4424   1.00  0   1.00
## Educational.special.needs                        15 4424   0.00  0   0.00
## Debtor                                           16 4424   0.00  0   0.00
## Tuition.fees.up.to.date                          17 4424   1.00  0   1.00
## Gender                                           18 4424   1.00  0   1.00
## Scholarship.holder                               19 4424   0.00  0   0.00
## Age.at.enrollment                                20 4424  20.00  0  20.00
## International                                    21 4424   0.00  0   0.00
## Curricular.units.1st.sem..credited.              22 4424   0.00  0   0.00
## Curricular.units.1st.sem..enrolled.              23 4424   0.00  0   0.00
## Curricular.units.1st.sem..evaluations.           24 4424   0.00  0   0.00
## Curricular.units.1st.sem..approved.              25 4424   0.00  0   0.00
## Curricular.units.1st.sem..grade.                 26 4424   0.00  0   0.00
## Curricular.units.1st.sem..without.evaluations.   27 4424   0.00  0   0.00
## Curricular.units.2nd.sem..credited.              28 4424   0.00  0   0.00
## Curricular.units.2nd.sem..enrolled.              29 4424   0.00  0   0.00
## Curricular.units.2nd.sem..evaluations.           30 4424   0.00  0   0.00
## Curricular.units.2nd.sem..approved.              31 4424   0.00  0   0.00
## Curricular.units.2nd.sem..grade.                 32 4424   0.00  0   0.00
## Curricular.units.2nd.sem..without.evaluations.   33 4424   0.00  0   0.00
## Unemployment.rate                                34 4424  10.80  0  10.80
## Inflation.rate                                   35 4424   1.40  0   1.40
## GDP                                              36 4424   1.74  0   1.74
##                                                trimmed mad    min    max range
## Marital.Status                                    1.00   0   1.00   1.00     0
## Application.mode                                 17.00   0  17.00  17.00     0
## Application.order                                 5.00   0   5.00   5.00     0
## Course                                          171.00   0 171.00 171.00     0
## Daytime.evening.attendance                        1.00   0   1.00   1.00     0
## Previous.qualification                            1.00   0   1.00   1.00     0
## Previous.qualification..grade.                  122.00   0 122.00 122.00     0
## Nacionality                                       1.00   0   1.00   1.00     0
## Mother.s.qualification                           19.00   0  19.00  19.00     0
## Father.s.qualification                           12.00   0  12.00  12.00     0
## Mother.s.occupation                               5.00   0   5.00   5.00     0
## Father.s.occupation                               9.00   0   9.00   9.00     0
## Admission.grade                                 127.30   0 127.30 127.30     0
## Displaced                                         1.00   0   1.00   1.00     0
## Educational.special.needs                         0.00   0   0.00   0.00     0
## Debtor                                            0.00   0   0.00   0.00     0
## Tuition.fees.up.to.date                           1.00   0   1.00   1.00     0
## Gender                                            1.00   0   1.00   1.00     0
## Scholarship.holder                                0.00   0   0.00   0.00     0
## Age.at.enrollment                                20.00   0  20.00  20.00     0
## International                                     0.00   0   0.00   0.00     0
## Curricular.units.1st.sem..credited.               0.00   0   0.00   0.00     0
## Curricular.units.1st.sem..enrolled.               0.00   0   0.00   0.00     0
## Curricular.units.1st.sem..evaluations.            0.00   0   0.00   0.00     0
## Curricular.units.1st.sem..approved.               0.00   0   0.00   0.00     0
## Curricular.units.1st.sem..grade.                  0.00   0   0.00   0.00     0
## Curricular.units.1st.sem..without.evaluations.    0.00   0   0.00   0.00     0
## Curricular.units.2nd.sem..credited.               0.00   0   0.00   0.00     0
## Curricular.units.2nd.sem..enrolled.               0.00   0   0.00   0.00     0
## Curricular.units.2nd.sem..evaluations.            0.00   0   0.00   0.00     0
## Curricular.units.2nd.sem..approved.               0.00   0   0.00   0.00     0
## Curricular.units.2nd.sem..grade.                  0.00   0   0.00   0.00     0
## Curricular.units.2nd.sem..without.evaluations.    0.00   0   0.00   0.00     0
## Unemployment.rate                                10.80   0  10.80  10.80     0
## Inflation.rate                                    1.40   0   1.40   1.40     0
## GDP                                               1.74   0   1.74   1.74     0
##                                                skew kurtosis se
## Marital.Status                                  NaN      NaN  0
## Application.mode                                NaN      NaN  0
## Application.order                               NaN      NaN  0
## Course                                          NaN      NaN  0
## Daytime.evening.attendance                      NaN      NaN  0
## Previous.qualification                          NaN      NaN  0
## Previous.qualification..grade.                  NaN      NaN  0
## Nacionality                                     NaN      NaN  0
## Mother.s.qualification                          NaN      NaN  0
## Father.s.qualification                          NaN      NaN  0
## Mother.s.occupation                             NaN      NaN  0
## Father.s.occupation                             NaN      NaN  0
## Admission.grade                                -Inf      NaN  0
## Displaced                                       NaN      NaN  0
## Educational.special.needs                       NaN      NaN  0
## Debtor                                          NaN      NaN  0
## Tuition.fees.up.to.date                         NaN      NaN  0
## Gender                                          NaN      NaN  0
## Scholarship.holder                              NaN      NaN  0
## Age.at.enrollment                               NaN      NaN  0
## International                                   NaN      NaN  0
## Curricular.units.1st.sem..credited.             NaN      NaN  0
## Curricular.units.1st.sem..enrolled.             NaN      NaN  0
## Curricular.units.1st.sem..evaluations.          NaN      NaN  0
## Curricular.units.1st.sem..approved.             NaN      NaN  0
## Curricular.units.1st.sem..grade.                NaN      NaN  0
## Curricular.units.1st.sem..without.evaluations.  NaN      NaN  0
## Curricular.units.2nd.sem..credited.             NaN      NaN  0
## Curricular.units.2nd.sem..enrolled.             NaN      NaN  0
## Curricular.units.2nd.sem..evaluations.          NaN      NaN  0
## Curricular.units.2nd.sem..approved.             NaN      NaN  0
## Curricular.units.2nd.sem..grade.                NaN      NaN  0
## Curricular.units.2nd.sem..without.evaluations.  NaN      NaN  0
## Unemployment.rate                               NaN      NaN  0
## Inflation.rate                                  NaN      NaN  0
## GDP                                             NaN      NaN  0
# === MEMERIKSA KORELASI ANTAR VARIABEL ===
num_cols <- sapply(data, is.numeric)
corr_matrix <- cor(data[, num_cols], use = "complete.obs")
## Warning in cor(data[, num_cols], use = "complete.obs"): the standard deviation
## is zero
corrplot(corr_matrix, method = "color", type = "upper", tl.cex = 0.7)

# === REGRESI LOGISTIK ===
data_log <- data %>% filter(target %in% c("Graduate", "Dropout"))

set.seed(123)
split <- sample.split(data_log$target, SplitRatio = 0.7)
train <- subset(data_log, split == TRUE)
test <- subset(data_log, split == FALSE)

# Model regresi logistik
log_model <- glm(target ~ Admission.grade +
                   Curricular.units.1st.sem..approved. +
                   Unemployment.rate + Inflation.rate + GDP,
                 data = train, family = "binomial")
## Warning: glm.fit: algorithm did not converge
# Periksa koefisien model
summary(log_model)
## 
## Call:
## glm(formula = target ~ Admission.grade + Curricular.units.1st.sem..approved. + 
##     Unemployment.rate + Inflation.rate + GDP, family = "binomial", 
##     data = train)
## 
## Coefficients: (5 not defined because of singularities)
##                                     Estimate Std. Error z value Pr(>|z|)
## (Intercept)                           -26.57    6400.31  -0.004    0.997
## Admission.grade                           NA         NA      NA       NA
## Curricular.units.1st.sem..approved.       NA         NA      NA       NA
## Unemployment.rate                         NA         NA      NA       NA
## Inflation.rate                            NA         NA      NA       NA
## GDP                                       NA         NA      NA       NA
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 0.0000e+00  on 3095  degrees of freedom
## Residual deviance: 1.7962e-08  on 3095  degrees of freedom
## AIC: 2
## 
## Number of Fisher Scoring iterations: 25
# Prediksi
log_prob <- predict(log_model, newdata = test, type = "response")
log_class <- ifelse(log_prob > 0.5, "Graduate", "Dropout") %>% as.factor()

# Memeriksa distribusi kelas pada hasil prediksi
table(log_class)
## log_class
## Dropout 
##    1328
# Memastikan kedua kelas ada di data uji dan prediksi
if (length(unique(test$target)) == 2 && length(unique(log_class)) == 2) {
  confusionMatrix(log_class, test$target)
} else {
  message("Data uji atau prediksi tidak mengandung dua kelas yang berbeda.")
}
## Data uji atau prediksi tidak mengandung dua kelas yang berbeda.
# === LDA ===
# Cek distribusi setiap variabel dalam setiap kelas target sebelum LDA
vars <- c("Admission.grade", "Curricular.units.1st.sem..approved.",
          "Unemployment.rate", "Inflation.rate", "GDP")

# Tampilkan ringkasan per kelas
for (v in vars) {
  print(paste("Distribusi untuk", v))
  print(by(train[[v]], train$target, summary))
}
## [1] "Distribusi untuk Admission.grade"
## train$target: Dropout
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   127.3   127.3   127.3   127.3   127.3   127.3 
## [1] "Distribusi untuk Curricular.units.1st.sem..approved."
## train$target: Dropout
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0       0       0       0 
## [1] "Distribusi untuk Unemployment.rate"
## train$target: Dropout
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    10.8    10.8    10.8    10.8    10.8    10.8 
## [1] "Distribusi untuk Inflation.rate"
## train$target: Dropout
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     1.4     1.4     1.4     1.4     1.4     1.4 
## [1] "Distribusi untuk GDP"
## train$target: Dropout
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.74    1.74    1.74    1.74    1.74    1.74
# Periksa variasi dalam setiap kelas untuk setiap variabel
valid_vars <- vars[sapply(vars, function(v) {
  all(tapply(train[[v]], train$target, function(x) length(unique(x))) > 1)
})]

# Periksa apakah masih ada variabel valid untuk LDA
if (length(valid_vars) >= 1) {
  
  # Buat formula LDA dinamis
  lda_formula <- as.formula(paste("target ~", paste(valid_vars, collapse = " + ")))
  
  # Fit LDA model
  lda_model <- lda(lda_formula, data = train)
  
  # Prediksi dan evaluasi
  lda_pred <- predict(lda_model, test)
  confusionMatrix(lda_pred$class, test$target)
  
  # Simpan hasil komponen LDA ke data test
  test$LDA1 <- lda_pred$x[, 1]
  if (ncol(lda_pred$x) > 1) {
    test$LDA2 <- lda_pred$x[, 2]
    ggplot(test, aes(x = LDA1, y = LDA2, color = target)) +
      geom_point(alpha = 0.7) +
      labs(title = "LDA Scatter Plot (2D)", x = "LDA 1", y = "LDA 2") +
      theme_minimal()
  } else {
    ggplot(test, aes(x = LDA1, fill = target)) +
      geom_density(alpha = 0.7) +
      labs(title = "LDA Projection (1D)", x = "LDA 1", y = "Density") +
      theme_minimal()
  }
  
} else {
  message("Tidak ada variabel yang memiliki variasi cukup dalam setiap kelas untuk LDA.")
}
## Tidak ada variabel yang memiliki variasi cukup dalam setiap kelas untuk LDA.
# === UJI ASUMSI LDA ===
# Uji Normalitas untuk setiap kelas (contoh untuk variabel Admission.grade)
# Uji normalitas hanya jika nilai tidak identik
unique_test <- by(data$Admission.grade, data$target, function(x) {
  if (length(unique(x)) > 1) {
    return(shapiro.test(x))
  } else {
    return("Semua nilai identik, tidak bisa dilakukan uji normalitas.")
  }
})
print(unique_test)
## data$target: Dropout
## [1] "Semua nilai identik, tidak bisa dilakukan uji normalitas."
# Uji Homogenitas Varians (Box's M Test)
# === UJI ASUMSI LDA ===
# Pastikan fungsi boxM tersedia
if (!require("biotools")) install.packages("biotools")
## Loading required package: biotools
## ---
## biotools version 4.3
library(biotools)

# Filter hanya data dengan dua kelas
lda_data <- data %>% filter(target %in% c("Graduate", "Dropout"))

# Pilih variabel yang tidak konstan antar kelas
vars <- c("Admission.grade", "Unemployment.rate", "Inflation.rate", "GDP")
valid_vars <- vars[sapply(vars, function(v) {
  all(tapply(lda_data[[v]], lda_data$target, function(x) length(unique(x)) > 1))
})]

if (length(valid_vars) >= 2) {
  boxM_result <- boxM(lda_data[, valid_vars], lda_data$target)
  print(boxM_result)
} else {
  message("Tidak cukup variabel dengan variasi untuk menjalankan Box's M Test.")
}
## Tidak cukup variabel dengan variasi untuk menjalankan Box's M Test.

Including Plots

You can also embed plots, for example:

## Warning in cor(data[, num_cols], use = "complete.obs"): the standard deviation
## is zero

## LDA model tidak tersedia, visualisasi tidak dilakukan.

Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.