Data Exploration

Practicum ~ Week 4

Logo

1. Pendahuluan

1.1 Tujuan

Dataset ini digunakan untuk menganalisis kinerja pembelajaran siswa berdasarkan beberapa faktor seperti jenis kelamin, jumlah ketidakhadiran, dan waktu belajar mandiri per minggu. Tujuannya adalah untuk:

  • Melihat hubungan antara kebiasaan belajar dengan hasil akademik di berbagai mata pelajaran,
  • Mengidentifikasi pola yang memengaruhi prestasi siswa, dan
  • Membantu guru atau peneliti memahami faktor-faktor yang paling berpengaruh terhadap nilai siswa.

1.2 Deskripsi Dataset

# VARIABLE CLASSIFICATION TABLE – Learning Performance Dataset

# 1. Load Required Libraries 
library(knitr)
library(kableExtra)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:kableExtra':
## 
##     group_rows
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# 2. Create Variable Classification Table 
variable_classification <- data.frame(
  Column = c(
    "first_name", 
    "gender", 
    "absence_days", 
    "weekly_self_study_hours", 
    "math_score", 
    "history_score", 
    "physics_score", 
    "chemistry_score", 
    "biology_score", 
    "english_score", 
    "geography_score"
  ),
  
  Data_Type = c(
    "Categorical", 
    "Categorical", 
    "Numerical", 
    "Numerical", 
    "Numerical", 
    "Numerical", 
    "Numerical", 
    "Numerical", 
    "Numerical", 
    "Numerical", 
    "Numerical"
  ),
  
  Subtype = c(
    "Nominal", 
    "Nominal", 
    "Discrete", 
    "Continuous", 
    "Continuous", 
    "Continuous", 
    "Continuous", 
    "Continuous", 
    "Continuous", 
    "Continuous", 
    "Continuous"
  ),
  
  Description = c(
    "Student's first name", 
    "Student's gender (male/female)", 
    "Number of days the student was absent", 
    "Average number of self-study hours per week", 
    "Score obtained in Mathematics", 
    "Score obtained in History", 
    "Score obtained in Physics", 
    "Score obtained in Chemistry", 
    "Score obtained in Biology", 
    "Score obtained in English", 
    "Score obtained in Geography"
  )
)

# 3. Generate Styled Table 
variable_classification %>%
  kbl(
    caption = "Table 1. Variable Classification for the Learning Performance Dataset",
    align = c("l", "c", "c", "l"),  # align columns (left for 1 & 4)
    col.names = c("Column", "Data Type", "Subtype", "Description"),
    escape = FALSE
  ) %>%
  kable_classic(full_width = FALSE, html_font = "Poppins") %>%
  
  # Apply pastel background per column + alignment fix
  column_spec(1, bold = TRUE, color = "#3A3A3A", background = "#FFE6E6", width = "4cm", extra_css = "text-align: left;") %>%  
  column_spec(2, color = "#3A3A3A", background = "#E6E6FA", width = "3cm") %>%               
  column_spec(3, color = "#3A3A3A", background = "#E0F7FA", width = "3cm") %>%               
  column_spec(4, color = "#3A3A3A", background = "#E8F5E9", width = "8cm", extra_css = "text-align: left;") %>%               
  
  # Add top header (pastel title bar)
  add_header_above(
    c("Data Description Table" = 4), 
    bold = TRUE, 
    color = "white", 
    background = "#B4C7E7",  
    line = TRUE
  ) %>%
  
  # Apply global styling
  kable_styling(
    bootstrap_options = c("hover", "condensed", "responsive"),
    position = "center",
    font_size = 14,
    fixed_thead = TRUE
  )
Table 1. Variable Classification for the Learning Performance Dataset
Data Description Table
Column Data Type Subtype Description
first_name Categorical Nominal Student’s first name
gender Categorical Nominal Student’s gender (male/female)
absence_days Numerical Discrete Number of days the student was absent
weekly_self_study_hours Numerical Continuous Average number of self-study hours per week
math_score Numerical Continuous Score obtained in Mathematics
history_score Numerical Continuous Score obtained in History
physics_score Numerical Continuous Score obtained in Physics
chemistry_score Numerical Continuous Score obtained in Chemistry
biology_score Numerical Continuous Score obtained in Biology
english_score Numerical Continuous Score obtained in English
geography_score Numerical Continuous Score obtained in Geography

Totalnya dataset ini mencakup data performa siswa di tujuh mata pelajaran utama, serta kebiasaan dan faktor personal yang bisa memengaruhi nilai mereka.

1.3 Konteks Kasus

Dataset ini bisa dianggap sebagai data hasil survei atau observasi di sebuah sekolah menengah atau universitas. Fokusnya adalah untuk:

  • Mengetahui apakah siswa yang belajar lebih banyak jamnya per minggu mendapatkan nilai lebih tinggi,
  • Melihat pengaruh absensi terhadap prestasi belajar, dan
  • Membandingkan performa akademik antara siswa laki-laki dan perempuan.

Dengan analisis ini, bisa dibuat kesimpulan seperti: “Siswa dengan tingkat kehadiran tinggi dan jam belajar mandiri lebih banyak cenderung memiliki nilai yang lebih baik di sebagian besar mata pelajaran.

2. Persiapan Data

# DATA PREPARATION: Clean, Process, and Display Interactive Table


library(readxl)
library(dplyr)
library(reactable)
library(htmltools)

# 1. Import dataset
data_raw <- read_excel("kinerja pembelajaran (statistik).xlsx")

# 2. Clean and prepare data
data_clean <- data_raw %>%
  rename_with(~ gsub("\\s+", "_", .x)) %>%
  mutate(across(where(is.character), trimws)) %>%
  mutate(
    RecordID = sprintf("R%04d", 1:n()),
    EntryDate = Sys.Date(),
    RandomScore = round(runif(n(), 60, 100), 1)
  )

# 3. Create interactive table with dropdown + animated pagination
htmltools::browsable(
  htmltools::tagList(
    
    # Dropdown control for entries per page
    tags$div(
      style = "display:flex; align-items:center; gap:6px; margin-bottom:10px; font-size:14px;",
      tags$span("Showing"),
      tags$select(
        id = "pageSizeSelect",
        style = "padding:3px 6px; border-radius:4px; border:1px solid #ccc; font-size:14px;",
        tags$option(value = 10, "10"),
        tags$option(value = 25, "25"),
        tags$option(value = 50, "50"),
        tags$option(value = 100, "100")
      ),
      tags$span("entries")
    ),
    
    # Reactable table
    reactable(
      data_clean,
      elementId = "myTable",
      searchable = TRUE,
      bordered = TRUE,
      striped = TRUE,
      highlight = TRUE,
      resizable = TRUE,
      defaultPageSize = 10,
      wrap = FALSE,
      fullWidth = TRUE,
      defaultColDef = colDef(align = "center"),
      
      theme = reactableTheme(
        headerStyle = list(
          background = "#f7f7f7",
          fontWeight = "bold",
          borderBottom = "2px solid #ddd"
        ),
        
        # Pagination area (clear background)
        paginationStyle = list(
          background = "transparent",
          borderTop = "1px solid #ddd",
          padding = "8px 0"
        ),
        
        # Pagination buttons with animation
        pageButtonStyle = list(
          background = "#ffffff",
          border = "1px solid #90CAF9",
          color = "#0D47A1",
          borderRadius = "6px",
          padding = "4px 10px",
          margin = "0 3px",
          transition = "all 0.2s ease-in-out",
          boxShadow = "0 1px 3px rgba(0,0,0,0.1)",
          fontWeight = "500"
        ),
        pageButtonHoverStyle = list(
          background = "#E3F2FD",
          border = "1px solid #42A5F5",
          transform = "scale(1.05)"
        ),
        pageButtonActiveStyle = list(
          background = "#1E88E5",
          color = "white",
          transform = "scale(1.05)"
        )
      )
    ),
    
    # JavaScript to change number of entries dynamically
    tags$script(HTML("
      document.getElementById('pageSizeSelect').addEventListener('change', function() {
        const newSize = parseInt(this.value);
        const tbl = window.reactable.getInstance('myTable');
        if (tbl) tbl.setPageSize(newSize);
      });
    "))
  )
)
Showing entries

3. Visualisasi

3.1 Bar Chart

  • Definisi

    Bar Chart adalah jenis visualisasi data yang digunakan untuk mewakili Data kategoris dengan bar persegi panjang. Setiap tinggi (atau panjang) bar sesuai dengan nilai atau frekuensi suatu kategori, sehingga mudah untuk membandingkan jumlah di berbagai kelompok.

  • Aturan Penggunaan

    1. Gunakan untuk data kategorikal seperti kota, jenis barang, jurusan, atau tingkat kepuasan.

    2. Batang mewakili nilai atau frekuensi dari tiap kategori.

    3. Tinggi atau panjang batang harus proporsional terhadap nilai datanya.

    4. Sumbu X atau Y harus diberi label dengan jelas (kategori dan nilai).

    5. Gunakan jarak antar batang yang sama, agar perbandingan mudah dibaca.

    6. Warna dan ukuran batang konsisten, jangan terlalu ramai agar tidak membingungkan.

    7. Cocok dipakai untuk:

      • Data numerik diskrit, seperti jumlah barang atau frekuensi.
      • Data kategoris ordinal, seperti tingkat kepuasan (rendah, sedang, tinggi).
  • Kelebihan

    1. Mudah dipahami secara visual, bahkan oleh orang awam.
    2. Memudahkan perbandingan antar kategori (mana yang lebih tinggi/rendah).
    3. Dapat menunjukkan pola atau tren sederhana secara cepat.
    4. Fleksibel: bisa vertikal, horizontal, atau bertumpuk (stacked).
    5. Cocok digunakan untuk menunjukkan kontribusi tiap kategori (misalnya total penjualan per kota).
  • Kekurangan

    1. Tidak cocok untuk data waktu berkelanjutan (time series) lebih baik pakai line chart.
    2. Jika kategorinya terlalu banyak, grafik jadi sulit dibaca dan padat.
    3. Perbedaan kecil antar batang kadang sulit dibedakan secara visual.
    4. Tidak bisa menunjukkan hubungan antar variabel, hanya membandingkan satu variabel terhadap kategori.
# LIBRARIES
library(ggplot2)
library(dplyr)
library(readxl)

# READ EXCEL DATA 
data <- read_excel("kinerja pembelajaran (statistik).xlsx", sheet = "Lembar1")

# COUNT STUDENTS BY GENDER 
gender_count <- data %>%
  group_by(gender) %>%
  summarise(Student_Count = n())

# CREATE A CLEAN BAR CHART 
ggplot(gender_count, aes(x = gender, y = Student_Count, fill = gender)) +
  geom_bar(stat = "identity", width = 0.6) +
  
  # Add value labels on top of the bars
  geom_text(aes(label = Student_Count),
            vjust = -0.2,             # position labels slightly above bars
            size = 6,                 # larger font size for clarity
            color = "black",          # high contrast text
            fontface = "bold") +      # bold text for readability
  
  # Pastel color palette
  scale_fill_manual(values = c("#FFB6B9", "#BBDED6")) +
  
  # Titles and centered alignment
  labs(
    title = "Number of Students by Gender",
    x = "Gender",
    y = "Number of Students"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(size = 16, face = "bold", hjust = 0.5, margin = margin(b = 10)),
    axis.title.x = element_text(size = 12, face = "bold", margin = margin(t = 10)),
    axis.title.y = element_text(size = 12, face = "bold", margin = margin(r = 10)),
    axis.text = element_text(size = 10),
    legend.position = "none",
    plot.background = element_rect(fill = "#FFF8F3", color = NA)
  ) +
  
  # Add some space at the top so labels don’t overlap with the chart border
  expand_limits(y = max(gender_count$Student_Count) + 2)

3.2 Histogram

  • Definisi

    Histogram adalah representasi grafis dari distribusi data numerik. Histogram membagi data ke dalam interval, yang dikenal sebagai bin, dan menampilkan frekuensi titik data dalam setiap bin. Visualisasi ini membantu mengidentifikasi pola-pola seperti tendensi sentral, sebaran, kemiringan, dan keberadaan beberapa modus dalam data (Wickham2016).

  • Aturan Penggunaan

    1. Gunakan untuk data numerik (berupa angka) bukan data kategori.

    2. Data dibagi menjadi beberapa interval atau “bin”, misalnya 0–10, 10–20, dst.

    3. Tinggi batang menunjukkan frekuensi (berapa banyak data) dalam setiap bin.

    4. Tidak boleh ada jarak antar batang, karena histogram menunjukkan rentang nilai yang berurutan (kontinu).

    5. Sumbu X = interval data, sumbu Y = frekuensi kemunculan data.

    6. Cocok digunakan untuk:

      • Mengetahui bentuk distribusi data (normal, miring, atau bimodal).
      • Melihat sebaran dan kecenderungan nilai dalam dataset.
  • Kelebihan

    1. Bisa menunjukkan pola sebaran data angka dengan jelas (misalnya data miring ke
      kanan, normal, atau punya dua puncak).
    2. Membantu kita melihat di rentang mana data paling banyak muncul — jadi tahu nilai yang sering keluar.
    3. Mudah dibaca dan dipahami secara visual, jadi cocok buat menjelaskan data ke orang awam.
    4. Bisa membantu mendeteksi penyimpangan atau data yang aneh (outlier).
    5. Berguna untuk menilai rata-rata, persebaran, dan kecenderungan data secara umum.
  • Kekurangan

    1. Hanya cocok untuk data numerik kontinu, tidak bisa untuk kategori seperti nama kota atau jenis barang.
    2. Pemilihan jumlah bin (interval) sangat memengaruhi tampilan — terlalu sedikit bin membuat
      data tampak kasar, terlalu banyak bin membuat data tampak acak.
    3. Sulit dibandingkan antar kelompok jika lebih dari satu dataset.
    4. Tidak menunjukkan nilai individu, hanya kelompok intervalnya.
    5. Jika datanya sedikit, hasil histogram bisa menyesatkan atau tidak representatif.
# Load libraries
library(readxl)
library(ggplot2)
library(tidyr)
library(dplyr)

# Read Excel file
data <- read_excel("kinerja pembelajaran (statistik).xlsx")

# Convert to long format (adjust column names to match your file)
data_long <- data %>%
  pivot_longer(
    cols = c(math_score, history_score, physics_score, chemistry_score, biology_score, english_score, geography_score),
    names_to = "subject",
    values_to = "score"
  )

# Create pastel-colored histograms per subject
ggplot(data_long, aes(x = score, fill = subject)) +
  geom_histogram(bins = 8, color = "white", alpha = 0.9) +
  scale_fill_manual(values = c("#FFB7B2", "#FFD1DC", "#B5EAD7", "#C7CEEA", "#FDFD96", "#E2F0CB", "#E0BBE4")) +
  facet_wrap(~subject, scales = "free_y") +
  labs(
    title = "Distribution of Student Scores per Subject",
    x = "Score",
    y = "Frequency"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    legend.position = "none",
    strip.text = element_text(face = "bold", color = "#E75480"),
    plot.title = element_text(face = "bold", color = "#E75480", hjust = 0.5)
  )

3.3 Boxplot

  • Definisi

    Boxplot adalah representasi visual dari distribusi data yang meringkas ringkasan lima angka utama: minimum, kuartil pertama (Q1), median (Q2), kuartil ketiga (Q3), dan maksimum.

  • Aturan Penggunaan

    1. Digunakan untuk menunjukkan penyebaran dan sebaran data angka (data numerik).
    2. Menampilkan nilai minimum, maksimum, median (nilai tengah), kuartil bawah, dan kuartil atas dalam satu gambar.
    3. Cocok dipakai untuk membandingkan sebaran data dari beberapa kelompok (misalnya nilai siswa per kelas, atau penghasilan antar daerah).
    4. Outlier (data yang jauh berbeda) bisa terlihat jelas lewat titik di luar “kotak”.
    5. Pastikan datanya berupa data kontinu atau numerik, bukan data kategori.
  • Kelebihan

    1. Mudah melihat sebaran dan persebaran data secara keseluruhan.
    2. Bisa menunjukkan median, variasi, dan outlier dalam satu tampilan.
    3. Cocok untuk membandingkan beberapa kelompok data sekaligus.
    4. Efisien, karena meringkas banyak data hanya dengan satu diagram.
    5. Membantu mendeteksi data yang tidak normal atau menyimpang.
  • Kekurangan

    1. Tidak menunjukkan detail tiap data, hanya ringkasan (seperti median dan kuartil).
    2. Sulit dipahami oleh orang awam yang belum terbiasa dengan konsep median atau kuartil.
    3. Tidak cocok untuk data kategori atau nominal.
    4. Tidak menunjukkan pola distribusi secara lengkap, hanya bentuk umum dan
      jangkauannya saja.
# Load library
library(readxl)
library(tidyr)
library(ggplot2)
library(dplyr)

# 1. Read Data from Excel File 
data <- read_excel("kinerja pembelajaran (statistik).xlsx")

# 2. Convert Data to Long Format 
data_long <- data %>%
  pivot_longer(
    cols = c(biology_score, chemistry_score, english_score,
             geography_score, history_score, math_score, physics_score),
    names_to = "Subject",
    values_to = "Score"
  )

# 3. Create Pastel Boxplots for Male vs Female 
ggplot(data_long, aes(x = gender, y = Score, fill = gender)) +
  geom_boxplot(alpha = 0.85, color = "white", outlier.shape = 21, outlier.fill = "#FFB6C1") +
  facet_wrap(~ Subject, ncol = 3) +
  scale_fill_manual(
    values = c(
      "female" = "#FFB6C1",  # soft pastel pink
      "male"   = "#A7C7E7"   # baby pastel blue
    )
  ) +
  labs(
    title = "Boxplot of All Subject Scores by Gender",
    x = "Gender",
    y = "Score"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", color = "#E75480", 
                              margin = margin(b=10)),
    strip.text = element_text(face = "bold", color = "#444444"),
    axis.title.x = element_text(face = "bold"),
    axis.title.y = element_text(face = "bold"),
    axis.text = element_text(size = 10),
    legend.position = "none",
    panel.grid.major.x = element_blank(),
    plot.background = element_rect(fill = "#FFF8F3", color = NA)
  )

3.4 Pie Chart

  • Definisi

    Pie chart adalah jenis grafik lingkaran yang digunakan untuk menampilkan data dalam bentuk proporsi berdasarkan bagian-bagian lingkaran, dengan masing-masing bagian mencerminkan persentase dari keseluruhan.

  • Aturan Penggunaan

    1. Dipakai untuk menunjukkan perbandingan bagian terhadap keseluruhan (misalnya persentase
      penjualan tiap produk atau proporsi jenis kelamin).
    2. Total seluruh bagian harus 100% atau satu kesatuan penuh (1 lingkaran = 100%).
    3. Cocok digunakan untuk data kategori yang jumlahnya tidak terlalu banyak (idealnya 3–6 kategori).
    4. Setiap potongan (slice) mewakili persentase atau jumlah dari tiap kategori.
    5. Gunakan warna yang berbeda dan kontras agar tiap bagian mudah dibedakan.
    6. Jangan gunakan jika kategori terlalu banyak atau nilainya mirip — nanti hasilnya susah dibaca.
  • Kelebihan

    1. Mudah dipahami secara visual, terutama untuk melihat proporsi bagian terhadap keseluruhan.
    2. Menarik secara tampilan dan sering dipakai dalam presentasi atau laporan umum.
    3. Memudahkan kita melihat bagian mana yang paling besar dan paling kecil.
    4. Cocok untuk menampilkan data sederhana dengan sedikit kategori.
  • Kekurangan

    1. Sulit dibandingkan antar kategori kalau ukuran potongannya mirip.
    2. Tidak cocok kalau terlalu banyak kategori, karena potongannya jadi kecil dan membingungkan.
    3. Tidak bisa menunjukkan perubahan dari waktu ke waktu (lebih baik pakai line chart untuk itu).
    4. Tidak akurat untuk analisis mendetail, karena ukuran visual potongan kadang menipu.
    5. Sulit dibaca jika tanpa label atau persentase yang jelas.
# Libraries 
library(readxl)
library(ggplot2)
library(dplyr)
library(tidyr)
library(scales)

# Read Excel File 
data <- read_excel("kinerja pembelajaran (statistik).xlsx")

# Ensure all column names are lowercase
names(data) <- tolower(names(data))

# Convert to Long Format (combine all subject scores) 
data_long <- data %>%
  pivot_longer(
    cols = c(biology_score, chemistry_score, english_score,
             geography_score, history_score, math_score, physics_score),
    names_to = "Subject",
    values_to = "Score"
  )

# Calculate Gender Proportion per Subject 
prop_data <- data_long %>%
  group_by(Subject, gender) %>%
  summarise(Count = n(), .groups = "drop_last") %>%
  mutate(Proportion = Count / sum(Count)) %>%
  ungroup()

# Define Pastel Colors 
pastel_colors <- c("#FFB6C1", "#A7C7E7")  # soft pink & baby blue

# Format subject names for better readability
prop_data$Subject <- gsub("_", " ", prop_data$Subject)
prop_data$Subject <- tools::toTitleCase(prop_data$Subject)

# Plot Pie Charts per Subject 
ggplot(prop_data, aes(x = "", y = Proportion, fill = gender)) +
  geom_col(width = 1, color = "white", alpha = 0.95) +
  coord_polar(theta = "y") +
  facet_wrap(~ Subject, ncol = 3) +
  
  # Add percentage labels inside the pie slices
  geom_text(
    aes(label = paste0(round(Proportion * 100), "%")),
    position = position_stack(vjust = 0.5),
    color = "white", size = 4, fontface = "bold"
  ) +
  
  scale_fill_manual(values = pastel_colors, name = "Gender") +
  
  labs(
    title = "Relationship Between Gender and Performance per Subject",
    subtitle = "Each chart represents gender proportion in each subject",
    fill = "Gender"
  ) +
  
  # Theme Customization 
  theme_void(base_size = 13) +
  theme(
    # General appearance
    plot.background = element_rect(fill = "#FFF8FB", color = NA),
    legend.background = element_rect(fill = "#FFF8FB", color = NA),
    legend.position = "bottom",
    panel.spacing = unit(1.3, "lines"),
    
    # Title and subtitle 
    plot.title = element_text(
      size = 18, face = "bold", hjust = 0.5, color = "#C71585",
      margin = margin(b = 5)
    ),
    plot.subtitle = element_text(
      size = 12, hjust = 0.5, color = "#8B008B",
      margin = margin(b = 10)
    ),
    
    # Facet titles (subject names)
    strip.background = element_rect(fill = "#FADADD", color = NA),
    strip.text = element_text(size = 9.5, face = "bold", color = "#4B2E83"),
    
    # Legend text 
    legend.title = element_text(size = 11, face = "bold"),
    legend.text = element_text(size = 10)
  )

3.5 Scatter Plot

  • Definisi

    Scatter plot atau diagram sebar adalah grafik yang menampilkan titik-titik data dibidang koordinat (X dan Y). Setiap titik menunjukkan dua nilai — satu untuk sumbu X dan satu untuk sumbu Y. Diagram ini dipakai untuk melihat hubungan atau pola antara dua variable

  • Aturan Penggunaan

  1. Gunakan saat kamu ingin melihat hubungan (korelasi) antara dua data angka.
  2. Sumbu X dan Y harus berisi variabel numerik.
  3. Setiap titik mewakili satu pasangan data (X, Y).
  4. Cocok untuk data yang banyak, supaya pola hubungan terlihat jelas.
  5. Kalau perlu, tambahkan garis tren (trend line) agar arah hubungan (positif, negatif, atau tidak ada hubungan) lebih mudah dilihat.
  • Kelebihan
  1. Bisa menunjukkan hubungan atau korelasi antara dua variabel dengan jelas.
  2. Mudah melihat pola — apakah data naik bersama, turun bersama, atau tidak berhubungan sama
    sekali.
  3. Dapat membantu mendeteksi outlier (data yang jauh dari pola umum).
  4. Cocok untuk analisis awal (eksplorasi data) sebelum melakukan perhitungan statistik.
  5. Bisa memperlihatkan kekuatan dan arah hubungan antara dua variabel.
  • Kekurangan
  1. Tidak cocok untuk data kategori, hanya bisa untuk data angka.
  2. Sulit dibaca jika data terlalu banyak dan titik-titiknya saling menumpuk.
  3. Tidak bisa menunjukkan hubungan sebab-akibat, hanya hubungan atau pola.
  4. Kalau tidak diberi penjelasan tambahan, orang awam bisa salah tafsir tentang maknanya.
  5. Tidak menunjukkan rata-rata atau sebaran seperti box plot atau histogram.
# Load Required Libraries 
library(readxl)
library(ggplot2)
library(dplyr)
library(tidyr)

# Read Excel File
data <- read_excel("kinerja pembelajaran (statistik).xlsx")

# Clean column names
names(data) <- make.names(names(data))

# Select only numeric columns
numeric_data <- data %>% select(where(is.numeric))

# Reference variable (independent variable)
y_var <- "absence.days"

# Convert data to long format
plot_data <- numeric_data %>%
  pivot_longer(
    cols = -all_of(y_var),
    names_to = "Subject",
    values_to = "Score"
  )

# Aesthetic Pastel Scatter Plot 
ggplot(plot_data, aes(x = Score, y = !!sym(y_var))) +
  geom_point(
    color = "#90CAF9",   # soft pastel blue
    fill = "#BBDEFB",
    shape = 21,
    alpha = 0.8,
    size = 3.5
  ) +
  geom_smooth(
    method = "lm",
    se = FALSE,
    color = "#F48FB1",   # soft pastel pink
    linewidth = 1.1
  ) +
  facet_wrap(~ Subject, scales = "free", ncol = 3) +
  labs(
    title = "Scatter Plot of Student Scores vs Absence per Subject",
    subtitle = paste("Comparison of each subject score with reference variable:", y_var),
    x = "Subject Score",
    y = "Number of Absence Days"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.background = element_rect(fill = "#FFF8F3", color = NA),   # warm cream background
    panel.background = element_rect(fill = "#FFFFFF", color = NA),
    panel.grid.major = element_line(color = "#F0E6EF"),
    panel.grid.minor = element_blank(),
    strip.background = element_rect(fill = "#E0BBE4", color = NA),  # pastel purple header
    strip.text = element_text(size = 11, face = "bold", color = "#4B4453"),
    plot.title = element_text(
      face = "bold", color = "#C06C84", size = 16,
      hjust = 0.5, margin = margin(b = 6)
    ),
    plot.subtitle = element_text(
      color = "#6C567B", size = 11.5,
      hjust = 0.5, margin = margin(b = 10)
    ),
    axis.title = element_text(color = "#4B4453", size = 11),
    axis.text = element_text(color = "#333333", size = 9.5),
    legend.position = "none"
  )
## `geom_smooth()` using formula = 'y ~ x'

3.6 Line Plot

  • Definisi

    Bagan Garis adalah alat visualisasi data yang menggambarkan bagaimana nilai berubah dalam suatu urutan, biasanya seiring waktu. Bagan ini menghubungkan titik-titik data dengan garis kontinu, sehingga ideal untuk menampilkan tren dan pola dalam data deret waktu (Wickham2016).

  • Aturan Penggunaan

    1. Dipakai untuk menunjukkan perubahan data dari waktu ke waktu (misalnya penjualan per bulan, suhu per hari, pertumbuhan penduduk per tahun).
    2. Sumbu X (horizontal) biasanya berisi waktu atau urutan data.
    3. Sumbu Y (vertikal) berisi nilai yang diukur (misalnya jumlah, suhu, atau nilai).
    4. Titik-titik data dihubungkan dengan garis untuk memperlihatkan arah tren (naik, turun, atau stabil).
    5. Gunakan skala yang konsisten supaya garisnya nggak menyesatkan.
    6. Bisa juga menampilkan lebih dari satu garis kalau ingin membandingkan beberapa kelompok
      data.
  • Kelebihan

  1. Mudah melihat tren atau pola perubahan dari waktu ke waktu.
  2. Menunjukkan arah pergerakan data (misalnya naik, turun, atau tetap).
  3. Cocok untuk data berurutan (time series).
  4. Bisa menampilkan beberapa seri data sekaligus untuk dibandingkan.
  5. Sederhana dan mudah dibaca, bahkan oleh orang yang tidak ahli statistik.
  • Kekurangan

    1. Tidak cocok untuk data kategori (misalnya nama kota atau jenis produk).
    2. Kalau data terlalu banyak, garisnya bisa terlalu rapat dan susah dibaca.
    3. Perbedaan kecil antar garis bisa sulit dilihat kalau warnanya mirip.
    4. Tidak terlalu berguna untuk menunjukkan jumlah total atau perbandingan antar kategori
      (lebih cocok pakai bar chart untuk itu).
# Learning Performance Data Visualization (Final & Polished)

# Load Libraries
library(readxl)
library(ggplot2)
library(dplyr)
library(tidyr)

# Read Excel File 
data <- read_excel("kinerja pembelajaran (statistik).xlsx")

# Clean Column Names (safe for R syntax) 
names(data) <- make.names(names(data))

# Select Only Numeric Columns 
numeric_data <- data %>% select(where(is.numeric))

# Soft Pastel Color Palette 
pastel_colors <- c(
  "#A3C4F3", "#FFB6B9", "#FFDAC1", "#E2F0CB",
  "#B5EAD7", "#C7CEEA", "#FFD3B6", "#F6B8B8"
)
pastel_colors <- rep(pastel_colors, length.out = length(unique(names(numeric_data))))


# 1 LINE PLOT: Relationship Between Absence and Scores per Subject
plot_absence <- numeric_data %>%
  pivot_longer(
    cols = -absence.days,
    names_to = "Subject",
    values_to = "Score"
  )

p1 <- ggplot(plot_absence, aes(x = absence.days, y = Score, color = Subject)) +
  geom_line(linewidth = 1.1, alpha = 0.9) +
  geom_point(size = 1.8, alpha = 0.85) +
  scale_color_manual(values = pastel_colors) +
  facet_wrap(~ Subject, scales = "free_y", ncol = 3) +
  labs(
    title = "Relationship Between Absence and Scores per Subject",
    x = "Number of Absence Days",
    y = "Score"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(
      face = "bold",
      color = "#D46A6A",
      size = 15,
      hjust = 0.5,
      vjust = 1.2,
      margin = margin(t = 6, b = 10)
    ),
    strip.background = element_rect(fill = "#FFE6EB", color = NA),
    strip.text = element_text(face = "bold", color = "#4B4453", size = 8.5),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_line(color = "#F2F2F2"),
    panel.spacing = unit(1.1, "lines"),
    axis.title.x = element_text(face = "bold", size = 11, margin = margin(t = 8)),
    axis.title.y = element_text(face = "bold", size = 11, margin = margin(r = 8)),
    plot.background = element_rect(fill = "#FFF8FB", color = NA),
    panel.background = element_rect(fill = "white", color = NA),
    legend.position = "none"
  )


# 2 LINE PLOT: Relationship Between Weekly Study Hours and Scores per Subject
plot_study <- numeric_data %>%
  pivot_longer(
    cols = -weekly_self_study_hours,
    names_to = "Subject",
    values_to = "Score"
  )

p2 <- ggplot(plot_study, aes(x = weekly_self_study_hours, y = Score, color = Subject)) +
  geom_line(linewidth = 1.1, alpha = 0.9) +
  geom_point(size = 1.8, alpha = 0.85) +
  scale_color_manual(values = pastel_colors) +
  facet_wrap(~ Subject, scales = "free_y", ncol = 3) +
  labs(
    title = "Relationship Between Weekly Study Hours and Scores per Subject",
    x = "Weekly Study Hours",
    y = "Score"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    # Main Title: perfectly centered & proportional
    plot.title = element_text(
      face = "bold",
      color = "#6A5ACD",
      size = 14,
      hjust = 0.5,  # precise centering
      vjust = 1.2,
      margin = margin(t = 6, b = 10)
    ),
    # Facet labels smaller to avoid overlap 
    strip.background = element_rect(fill = "#E0BBE4", color = NA),
    strip.text = element_text(face = "bold", color = "#4B4453", size = 8.5),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_line(color = "#F2F2F2"),
    panel.spacing = unit(1.1, "lines"),
    axis.title.x = element_text(face = "bold", size = 11, margin = margin(t = 8)),
    axis.title.y = element_text(face = "bold", size = 11, margin = margin(r = 8)),
    plot.background = element_rect(fill = "#FFF8FB", color = NA),
    panel.background = element_rect(fill = "white", color = NA),
    legend.position = "none"
    )
#view result p1
p1

#view result p2
p2

3.7 Density Plot

  • Definisi

    Density plot atau grafik kepadatan adalah grafik yang digunakan untuk menunjukkan sebaran data numerik (angka) seperti halnya histogram, tetapi bentuknya lebih halus karena menggunakan garis lengkung.

  • Aturan Penggunaan

    1. Gunakan untuk data numerik kontinu (misalnya berat badan, nilai ujian, pendapatan, suhu).
    2. Cocok saat ingin melihat bentuk distribusi data dengan lebih halus dan rapi daripada histogram.
    3. Kalau ingin membandingkan beberapa kelompok, bisa pakai warna berbeda di grafik yang sama.
    4. Gunakan skala yang sama kalau membandingkan lebih dari satu dataset, supaya perbandingan adil.
    5. Tidak cocok untuk data kategori.
  • Kelebihan Density Plot

    1. Menampilkan distribusi data dengan lebih halus dan jelas daripada histogram.
    2. Mudah membaca pola umum, seperti apakah data miring, normal, atau punya dua puncak.
    3. Cocok untuk perbandingan antar kelompok (misalnya nilai laki-laki vs perempuan).
    4. Tidak bergantung pada jumlah atau ukuran “bin” seperti histogram, jadi lebih fleksibel.
    5. Tampilan lebih rapi dan estetis untuk presentasi atau laporan.
  • Kekurangan Density Plot:

    1. Hanya bisa digunakan untuk data numerik kontinu, bukan kategori.
    2. Kurang akurat kalau data sedikit, karena garisnya bisa menipu bentuk distribusi sebenarnya.
    3. Sulit dipahami oleh orang awam, terutama jika belum terbiasa membaca grafik statistik.
    4. Tidak menunjukkan jumlah data secara langsung (karena fokusnya di bentuk sebaran, bukan
      frekuensi absolut).
    5. Bentuk grafik bisa berubah tergantung pada pengaturan “bandwidth” (tingkat kehalusan garis).
# DENSITY PLOT – Score Distribution by Subject and Gender

# Libraries 
library(ggplot2)
library(dplyr)
library(tidyr)
library(grid)

# Simulated Dataset 
set.seed(123)
data <- data.frame(
  gender = rep(c("Male", "Female"), each = 100),
  biology_score = rnorm(200, 80, 10),
  chemistry_score = rnorm(200, 82, 9),
  english_score = rnorm(200, 78, 8),
  geography_score = rnorm(200, 81, 9),
  history_score = rnorm(200, 79, 10),
  math_score = rnorm(200, 83, 9),
  physics_score = rnorm(200, 84, 8)
)

# Convert Data to Long Format 
data_long <- data %>%
  pivot_longer(
    cols = ends_with("_score"),
    names_to = "subject",
    values_to = "score"
  )

# Pastel Colors for Gender 
pastel_colors <- c("Male" = "#A0C4FF", "Female" = "#FFAFCC")


# Density Plot

density_plot <- ggplot(data_long, aes(x = score, fill = gender)) +
  geom_density(alpha = 0.55, color = NA) +
  facet_wrap(~subject, scales = "free", ncol = 3) +
  scale_fill_manual(values = pastel_colors) +
  labs(
    title = "Estimated Probability Distribution of Scores by Subject",
    subtitle = "Density plots per subject grouped by gender",
    x = "Score"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    # Main Title (centered & balanced)
    plot.title = element_text(
      size = 18, face = "bold",
      color = "#C2185B",
      hjust = 0.5, vjust = 1.2,
      margin = margin(b = 6)
    ),
    plot.subtitle = element_text(
      size = 13,
      color = "#7B1FA2",
      hjust = 0.5,
      margin = margin(b = 10)
    ),
    # Facet Labels 
    strip.background = element_rect(fill = "#FADADD", color = NA),
    strip.text = element_text(face = "bold", color = "#4B4453", size = 9),
    # Background & Panel Aesthetics 
    panel.background = element_rect(fill = "#FFF5F8", color = NA),
    plot.background = element_rect(fill = "#FFF5F8", color = NA),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_line(color = "#F0E6F6"),
    # Axes & Legend 
    axis.title.x = element_text(face = "bold", size = 11, margin = margin(t = 6)),
    axis.title.y = element_blank(),
    axis.text = element_text(size = 9),
    legend.position = "bottom",
    legend.title = element_blank(),
    legend.text = element_text(size = 10),
    # Overall Margins (avoid text clipping) 
    plot.margin = margin(t = 20, r = 20, b = 15, l = 70)
  )

# Add Vertical Label on the Left Side

grid.newpage()
grid.draw(ggplotGrob(density_plot))

grid.text(
  "Estimated Probability Density",
  x = unit(0.035, "npc"),  # fine-tuned alignment
  y = 0.5,
  rot = 90,
  gp = gpar(
    fontsize = 13.5,
    fontface = "bold",
    col = "#333333"
  )
)

3.8 Ridgeline Plot (opsional tambahan)

  • Definisi

    Ridgeline plot adalah gabungan beberapa density plot (grafik kepadatan) yang ditumpuk secara vertikal untuk membandingkan sebaran data dari beberapa kelompok.

  • Aturan Penggunaan

    1. Gunakan untuk data numerik kontinu yang dibagi ke dalam beberapa kelompok atau kategori
      (contohnya: nilai ujian per tahun, suhu per bulan, pendapatan per provinsi).
    2. Setiap kelompok harus punya jumlah data yang cukup agar bentuk distribusinya jelas.
    3. Urutkan kelompok secara logis (misalnya berdasarkan waktu atau kategori tertentu).
    4. Gunakan warna dan jarak antar lapisan yang konsisten supaya mudah dibaca.
    5. Hindari menumpuk terlalu banyak kelompok, karena bisa jadi berantakan.
  • Kelebihan

    1. Menampilkan banyak distribusi data sekaligus dalam satu grafik.
    2. Mudah membandingkan bentuk dan pergeseran sebaran antar kelompok.
    3. Tampilannya menarik dan estetik, cocok untuk presentasi atau laporan visual.
    4. Membantu menemukan pola tren waktu atau perbedaan antar kategori.
    5. Lebih ringkas dibanding menampilkan banyak histogram atau density plot terpisah.
  • Kekurangan

    1. Sulit dibaca kalau terlalu banyak kelompok ditampilkan sekaligus.
    2. Tidak menunjukkan nilai pasti atau jumlah data, hanya bentuk sebaran.
    3. Bisa menyesatkan jika skala antar kelompok tidak konsisten.
    4. Kurang cocok untuk audiens awam, karena bentuknya lebih kompleks dari grafik biasa.
    5. Membutuhkan alat visualisasi khusus (misalnya R, Python, atau aplikasi data science).
# RIDGELINE PLOT – Distribution of Student Scores by Subject and Gender

# LIBRARIES 
library(ggplot2)
library(dplyr)
library(tidyr)
library(ggridges)

# Simulated Data 
set.seed(123)
data <- data.frame(
  gender = rep(c("Male", "Female"), each = 100),
  biology_score   = rnorm(200, 80, 10),
  chemistry_score = rnorm(200, 82, 9),
  english_score   = rnorm(200, 78, 8),
  geography_score = rnorm(200, 81, 9),
  history_score   = rnorm(200, 79, 10),
  math_score      = rnorm(200, 83, 9),
  physics_score   = rnorm(200, 84, 8)
)

# Convert to Long Format 
data_long <- data %>%
  pivot_longer(
    cols = ends_with("_score"),
    names_to = "Subject",
    values_to = "Score"
  )

# Pastel Colors for Gender 
pastel_colors <- c("Male" = "#A0C4FF", "Female" = "#FFAFCC")


# Ridgeline Plot
ggplot(data_long, aes(x = Score, y = Subject, fill = gender)) +
  geom_density_ridges(
    alpha = 0.6,
    color = "white",
    scale = 1.1,
    rel_min_height = 0.01
  ) +
  scale_fill_manual(values = pastel_colors) +
  labs(
    title = "Comparison of Score Distributions Across Groups",
    subtitle = "Ridgeline plot of subject scores by gender",
    x = "Score",
    y = "Subject"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    # Title and Subtitle (Centered & Styled) 
    plot.title = element_text(
      size = 18, face = "bold",
      hjust = 0.5, color = "#C2185B"
    ),
    plot.subtitle = element_text(
      size = 13,
      hjust = 0.5,
      color = "#7B1FA2"
    ),
    # Axis Titles 
    axis.title.x = element_text(size = 12, face = "bold"),
    axis.title.y = element_text(size = 12, face = "bold"),
    # General Aesthetics 
    strip.text = element_text(size = 11, face = "bold"),
    panel.background = element_rect(fill = "#FFF8FB", color = NA),
    plot.background = element_rect(fill = "#FFF8FB", color = NA),
    # Legend 
    legend.position = "bottom",
    legend.title = element_blank(),
    legend.text = element_text(size = 11),
    # Margins 
    plot.margin = margin(15, 15, 15, 15)
  )
## Picking joint bandwidth of 3.01

4 Kesimpulan

4.1 Bar Chart – Jumlah Siswa Berdasarkan Gender

  • Visualisasi memperlihatkan bahwa jumlah siswa laki-laki dan perempuan relatif seimbang, tidak ada perbedaan besar di antara keduanya.
  • Kesetaraan komposisi ini memastikan bahwa analisis selanjutnya tidak bias terhadap gender.
  • Artinya, hasil perbandingan nilai atau performa akademik dapat dianggap objektif dan representatif.

4.2 Histogram – Distribusi Nilai per Mata Pelajaran

  • Histogram menunjukkan keragaman pola distribusi nilai antar mata pelajaran.
  • Mata pelajaran seperti Fisika, Matematika, dan Kimia cenderung memiliki nilai terkonsentrasi di rentang tinggi (80–90), menandakan penguasaan konsep yang baik.
  • Sementara Bahasa Inggris dan Sejarah menunjukkan sebaran yang lebih lebar dan bervariasi, menandakan perbedaan kemampuan yang lebih signifikan antar siswa.
  • Insight: beberapa pelajaran mungkin membutuhkan strategi pengajaran berbeda agar semua siswa dapat mencapai performa optimal.

4.3 Boxplot – Perbandingan Nilai Berdasarkan Gender

  • Dari boxplot, terlihat bahwa median nilai siswa laki-laki dan perempuan hampir sama pada semua mata pelajaran.
  • Munculnya outlier menandakan adanya kelompok siswa dengan performa yang jauh di atas atau di bawah rata-rata.
  • Sebaran nilai pada pelajaran sains cenderung lebih besar pada siswa laki-laki, menunjukkan variasi hasil belajar yang lebih lebar.
  • Insight: perbedaan prestasi lebih disebabkan oleh faktor individu dibandingkan faktor gender.

4.4 Pie Chart – Proporsi Gender per Mata Pelajaran

  • Proporsi gender di setiap pelajaran menunjukkan komposisi yang merata.
  • Tidak ada pelajaran yang didominasi oleh satu gender, baik di bidang sains maupun sosial.
  • Hal ini mencerminkan lingkungan belajar yang inklusif dan adil, di mana setiap siswa memiliki kesempatan yang sama untuk berkembang.

4.5 Scatter Plot – Hubungan Antara Nilai dan Absensi

  • Scatter plot menunjukkan pola negatif yang jelas antara jumlah absensi dan nilai.
  • Siswa dengan absensi lebih banyak cenderung memiliki nilai lebih rendah, terutama di pelajaran eksakta (Fisika, Matematika, Kimia).
  • Beberapa pelajaran seperti Bahasa Inggris dan Geografi memperlihatkan hubungan yang lebih
    lemah, mungkin karena sifatnya yang bisa dipelajari secara mandiri.
  • Insight: kehadiran di kelas sangat penting bagi pelajaran yang berbasis latihan dan konsep.

4.6 Line Plot – Tren Hubungan Absensi dan Nilai

  • Line plot memperkuat insight sebelumnya: semakin banyak absen, semakin menurun nilai rata-rata.
  • Penurunan paling signifikan terlihat pada Matematika dan Fisika.
  • Sedangkan pelajaran sosial** relatif lebih stabil, meskipun siswa memiliki tingkat absensi lebih tinggi.
  • Insight: sekolah dapat menggunakan informasi ini untuk meningkatkan kebijakan kehadiran dan membuat sistem peringatan dini bagi siswa yang sering absen.

4.7 Density Plot – Distribusi Nilai Berdasarkan Gender

  • Density plot menunjukkan bahwa laki-laki dan perempuan memiliki distribusi nilai yang hampir identik, artinya performa akademik keduanya relatif sama.
  • Sebagian besar nilai berada di sekitar 80–85, menandakan tingkat pencapaian belajar yang baik secara umum.
  • Beberapa pelajaran menunjukkan dua puncak distribusi (bimodal) ini bisa mengindikasikan adanya kelompok siswa dengan kemampuan yang berbeda (misal: yang memahami materi dan yang masih
    kesulitan).
  • Insight: pembelajaran dapat dipersonalisasi untuk mengakomodasi dua kelompok kemampuan tersebut.

4.8 Ridgeline Plot – Perbandingan Distribusi Beberapa Kelompok

  • Ridgeline plot memberikan gambaran menyeluruh tentang pola sebaran nilai antar pelajaran.
  • Pelajaran seperti Matematika, Kimia, dan Fisika memiliki puncak yang sempit dan tinggi — menunjukkan konsistensi hasil belajar.
  • Sementara Bahasa Inggris dan Sejarah menunjukkan distribusi yang lebih datar, menandakan
    tingkat variasi kemampuan yang lebih besar antar siswa.
  • Insight: kombinasi analisis ini mendukung penerapan strategi belajar diferensial, yaitu menyesuaikan metode pembelajaran dengan karakteristik tiap mata pelajaran.

4.9 Kesimpulan Umum

  1. Kedisiplinan hadir di kelas berpengaruh besar terhadap performa akademik, terutama untuk pelajaran berbasis konsep.
  2. Perbedaan gender tidak memengaruhi performa akademik secara signifikan, menunjukkan lingkungan belajar yang seimbang dan setara.
  3. Variasi hasil belajar antar pelajaran menandakan bahwa pendekatan pembelajaran tidak bisa diseragamkan.
  4. Data menunjukkan pentingnya strategi pengajaran yang fleksibel dan personal, untuk mengatasi perbedaan gaya belajar dan kemampuan siswa.
  5. Secara keseluruhan, kombinasi berbagai visualisasi (bar, histogram, boxplot, scatter, line, density, ridgeline) membantu membangun pemahaman menyeluruh tentang perilaku belajar dan hasil siswa.