output: html_document: toc: true toc_depth: 2 toc_float: true number_sections: false theme: flatly highlight: tango code_folding: show df_print: paged —

Ilustrasi Kasus

Aplikasi jejak karbon EcoTrack mencatat menit penggunaan harian dari 15 pengguna aktif dalam satu minggu:

22, 25, 19, 30, 24, 21, 45, 23, 20, 26, 24, 22, 18, 27, 23

# Data asli (sesuai urutan pada soal)
menit <- c(22, 25, 19, 30, 24, 21, 45, 23, 20, 26, 24, 22, 18, 27, 23)

n <- length(menit)                 # banyak data
data_ecotrack <- data.frame(Pengguna = paste0("P", 1:n), Menit = menit)

cat("Banyak data (n) =", n, "\n")
## Banyak data (n) = 15
cat("Data terurut     :", sort(menit), "\n")
## Data terurut     : 18 19 20 21 22 22 23 23 24 24 25 26 27 30 45
# Gambaran awal: menit penggunaan tiap pengguna
data_ecotrack$Pengguna <- factor(data_ecotrack$Pengguna, levels = data_ecotrack$Pengguna)

ggplot(data_ecotrack, aes(x = Pengguna, y = Menit,
                          fill = Menit == max(Menit))) +
  geom_col(width = 0.75, show.legend = FALSE) +
  geom_text(aes(label = Menit), vjust = -0.4, size = 3.6) +
  scale_fill_manual(values = c("FALSE" = warna_utama, "TRUE" = warna_outlier)) +
  labs(title = "Menit Penggunaan Harian EcoTrack per Pengguna",
       subtitle = "Batang oranye = nilai tertinggi (P7 = 45 menit) yang tampak mencolok",
       x = "Pengguna", y = "Menit per hari") +
  tema_ku


Soal 1 — Mean, Median, dan Modus (Manual + RStudio)

a. Perhitungan Manual

Mean (rata-rata) = jumlah seluruh data dibagi banyak data.

urut  <- sort(menit)
total <- sum(menit)

cat("Data terurut :", urut, "\n")
## Data terurut : 18 19 20 21 22 22 23 23 24 24 25 26 27 30 45
cat("Jumlah data (Σx) =", paste(urut, collapse = " + "), "=", total, "\n")
## Jumlah data (Σx) = 18 + 19 + 20 + 21 + 22 + 22 + 23 + 23 + 24 + 24 + 25 + 26 + 27 + 30 + 45 = 369
cat("Mean = Σx / n =", total, "/", n, "=", total / n, "\n")
## Mean = Σx / n = 369 / 15 = 24.6

Median = nilai tengah data terurut. Karena n = 15 (ganjil), median berada pada urutan ke-(n+1)/2.

posisi_median <- (n + 1) / 2
cat("Posisi median = (n + 1)/2 = (", n, "+ 1)/2 = data ke-", posisi_median, "\n")
## Posisi median = (n + 1)/2 = ( 15 + 1)/2 = data ke- 8
cat("Data ke-", posisi_median, "pada data terurut =", urut[posisi_median], "\n")
## Data ke- 8 pada data terurut = 23

Modus = nilai yang paling sering muncul. Tabel frekuensi:

tabel_frek <- as.data.frame(table(Menit = urut))
colnames(tabel_frek) <- c("Menit", "Frekuensi")
kable(tabel_frek, align = "c", caption = "Tabel frekuensi tiap nilai")
Tabel frekuensi tiap nilai
Menit Frekuensi
18 1
19 1
20 1
21 1
22 2
23 2
24 2
25 1
26 1
27 1
30 1
45 1
maks_frek <- max(tabel_frek$Frekuensi)
tabel_frek$Modus <- tabel_frek$Frekuensi == maks_frek

ggplot(tabel_frek, aes(x = Menit, y = Frekuensi, fill = Modus)) +
  geom_col(width = 0.7) +
  scale_fill_manual(values = c("FALSE" = "grey70", "TRUE" = warna_utama),
                    labels = c("Bukan modus", "Modus")) +
  scale_y_continuous(breaks = 0:maks_frek) +
  labs(title = "Frekuensi Tiap Nilai Menit",
       subtitle = "Batang biru = nilai dengan frekuensi tertinggi (modus)",
       x = "Menit penggunaan", y = "Frekuensi", fill = NULL) +
  tema_ku

b. Verifikasi dengan RStudio

# Fungsi modus (R tidak punya fungsi bawaan untuk modus statistik)
hitung_modus <- function(x) {
  frek <- table(x)
  as.numeric(names(frek)[frek == max(frek)])
}

rata2   <- mean(menit)
med     <- median(menit)
modus   <- hitung_modus(menit)

hasil_s1 <- data.frame(
  Ukuran = c("Mean", "Median", "Modus"),
  Nilai  = c(rata2, med, paste(modus, collapse = ", ")),
  Keterangan = c("Manual: 369 / 15",
                 "Manual: data ke-8",
                 paste0("Muncul ", maks_frek, " kali (data multimodus)"))
)
kable(hasil_s1, align = c("l", "c", "l"), caption = "Ringkasan Soal 1")
Ringkasan Soal 1
Ukuran Nilai Keterangan
Mean 24.6 Manual: 369 / 15
Median 23 Manual: data ke-8
Modus 22, 23, 24 Muncul 2 kali (data multimodus)
ggplot(data.frame(menit), aes(x = menit)) +
  geom_histogram(binwidth = 5, boundary = 15, closed = "left",
                 fill = warna_utama, colour = "white", alpha = 0.85) +
  geom_vline(aes(xintercept = rata2, colour = "Mean"),   linewidth = 1.2) +
  geom_vline(aes(xintercept = med,   colour = "Median"), linewidth = 1.2, linetype = "dashed") +
  scale_colour_manual(values = c("Mean" = warna_mean, "Median" = warna_median)) +
  scale_x_continuous(breaks = seq(15, 50, 5)) +
  labs(title = "Sebaran Data dengan Posisi Mean dan Median",
       subtitle = paste0("Mean = ", rata2, " menit  |  Median = ", med, " menit"),
       x = "Menit penggunaan", y = "Jumlah pengguna", colour = NULL) +
  tema_ku +
  theme(legend.position = "top")

Interpretasi: Rata-rata pengguna memakai EcoTrack selama 24.6 menit/hari, sedangkan nilai tengahnya 23 menit. Data bersifat multimodus (22, 23, 24 menit, masing-masing muncul 2 kali). Mean (24.6) lebih besar daripada median (23) karena tertarik oleh satu pengguna yang sangat lama (45 menit), sehingga median lebih mewakili pengguna “biasa” pada kasus ini.


Soal 2 — Q1, Q3, dan IQR (Manual + RStudio)

a. Perhitungan Manual

Sesuai modul, posisi kuartil ke-i dihitung dengan rumus \(Q_i = x_{\,i(n+1)/4}\). Bila posisinya pecahan, dilakukan interpolasi. Di R metode ini setara dengan quantile(..., type = 6).

kuartil_manual <- function(x, p) {
  x <- sort(x)
  pos    <- p * (length(x) + 1)          # posisi = i(n+1)/4
  bawah  <- floor(pos)
  atas   <- ceiling(pos)
  x[bawah] + (pos - bawah) * (x[atas] - x[bawah])
}

# --- Q1 ---
pos_q1 <- 1 * (n + 1) / 4
cat("Q1: posisi = 1 x (15+1)/4 =", pos_q1, "(bilangan bulat, tanpa interpolasi)\n")
## Q1: posisi = 1 x (15+1)/4 = 4 (bilangan bulat, tanpa interpolasi)
cat("    Q1 = data ke-", pos_q1, "=", urut[pos_q1], "\n\n")
##     Q1 = data ke- 4 = 21
# --- Q3 ---
pos_q3 <- 3 * (n + 1) / 4
cat("Q3: posisi = 3 x (15+1)/4 =", pos_q3, "(bilangan bulat, tanpa interpolasi)\n")
## Q3: posisi = 3 x (15+1)/4 = 12 (bilangan bulat, tanpa interpolasi)
cat("    Q3 = data ke-", pos_q3, "=", urut[pos_q3], "\n\n")
##     Q3 = data ke- 12 = 26
Q1_manual  <- kuartil_manual(menit, 0.25)
Q3_manual  <- kuartil_manual(menit, 0.75)
cat("IQR = Q3 - Q1 =", Q3_manual, "-", Q1_manual, "=", Q3_manual - Q1_manual, "\n")
## IQR = Q3 - Q1 = 26 - 21 = 5

b. Verifikasi dengan RStudio

# type = 6 -> posisi i(n+1)/4, sesuai rumus manual pada modul
Q1  <- quantile(menit, 0.25, type = 6, names = FALSE)
Q3  <- quantile(menit, 0.75, type = 6, names = FALSE)
IQR_val <- IQR(menit, type = 6)

kable(data.frame(
  Ukuran = c("Q1", "Q3", "IQR"),
  Manual = c(Q1_manual, Q3_manual, Q3_manual - Q1_manual),
  RStudio = c(Q1, Q3, IQR_val),
  Cocok = c(Q1_manual == Q1, Q3_manual == Q3, (Q3_manual - Q1_manual) == IQR_val)
), align = "c", caption = "Perbandingan hasil manual vs RStudio")
Perbandingan hasil manual vs RStudio
Ukuran Manual RStudio Cocok
Q1 21 21 TRUE
Q3 26 26 TRUE
IQR 5 5 TRUE
# Pagar dalam (Tukey fences) untuk mendeteksi pencilan
batas_bawah <- Q1 - 1.5 * IQR_val
batas_atas  <- Q3 + 1.5 * IQR_val
pencilan    <- menit[menit < batas_bawah | menit > batas_atas]

cat("Batas bawah = Q1 - 1.5 x IQR =", batas_bawah, "\n")
## Batas bawah = Q1 - 1.5 x IQR = 13.5
cat("Batas atas  = Q3 + 1.5 x IQR =", batas_atas, "\n")
## Batas atas  = Q3 + 1.5 x IQR = 33.5
cat("Pencilan (outlier)           =", pencilan, "\n")
## Pencilan (outlier)           = 45
# Boxplot digambar dari Q1 & Q3 (type = 6) agar konsisten dengan hasil di atas.
# (geom_boxplot bawaan ggplot2 memakai "hinges" yang bisa sedikit berbeda.)
whisker_bawah <- min(menit[menit >= batas_bawah])
whisker_atas  <- max(menit[menit <= batas_atas])
box_df <- data.frame(x = "", ymin = whisker_bawah, lower = Q1,
                     middle = med, upper = Q3, ymax = whisker_atas)

ggplot(box_df, aes(x = x)) +
  geom_boxplot(aes(ymin = ymin, lower = lower, middle = middle, upper = upper, ymax = ymax),
               stat = "identity", fill = "#AEC6F6", colour = warna_utama, width = 0.45) +
  geom_point(data = data.frame(x = "", y = pencilan), aes(y = y),
             colour = warna_outlier, size = 4) +
  geom_point(data = data.frame(x = "", y = rata2), aes(y = y),
             shape = 23, size = 4, fill = warna_mean, colour = "white") +
  annotate("text", x = 1.33, y = pencilan, label = paste0("Pencilan = ", pencilan),
           colour = warna_outlier, fontface = "bold", hjust = 0.5) +
  annotate("text", x = 1.33, y = rata2, label = paste0("Mean = ", rata2),
           colour = warna_mean, hjust = 0.5) +
  coord_flip(clip = "off") +
  labs(title = "Boxplot Menit Penggunaan EcoTrack",
       subtitle = paste0("Q1 = ", Q1, "  |  Median = ", med, "  |  Q3 = ", Q3, "  |  IQR = ", IQR_val),
       x = NULL, y = "Menit penggunaan") +
  tema_ku

Interpretasi: Q1 = 21 menit artinya 25% pengguna memakai EcoTrack ≤ 21 menit, dan Q3 = 26 menit artinya 75% pengguna memakai ≤ 26 menit (hanya 25% yang lebih dari itu). IQR = 5 menit, sehingga 50% pengguna di tengah hanya berbeda rentang 5 menit dan penggunaan mereka sangat seragam. Pengguna dengan durasi 45 menit berada di atas batas atas 33.5 menit sehingga dikategorikan pencilan. Karena IQR tidak terpengaruh nilai ekstrem, ia menggambarkan variasi pengguna “biasa” dengan lebih jujur.


Soal 3 — Varians dan Standar Deviasi (Manual + RStudio)

a. Perhitungan Manual

Data adalah sampel 15 pengguna, sehingga digunakan rumus sampel (pembagi n − 1):

\[s^2=\frac{\sum (x_i-\bar{x})^2}{n-1}\qquad s=\sqrt{s^2}\]

tabel_var <- data.frame(
  x        = urut,
  `x - mean`   = urut - rata2,
  `(x - mean)^2` = (urut - rata2)^2,
  check.names = FALSE
)

# Baris jumlah
baris_total <- data.frame(x = sum(urut),
                          `x - mean` = round(sum(urut - rata2), 10),
                          `(x - mean)^2` = sum((urut - rata2)^2),
                          check.names = FALSE)
rownames(baris_total) <- "Jumlah"

kable(rbind(tabel_var, baris_total), digits = 2, align = "c",
      caption = "Tabel bantu perhitungan varians (mean = 24.6)")
Tabel bantu perhitungan varians (mean = 24.6)
x x - mean (x - mean)^2
1 18 -6.6 43.56
2 19 -5.6 31.36
3 20 -4.6 21.16
4 21 -3.6 12.96
5 22 -2.6 6.76
6 22 -2.6 6.76
7 23 -1.6 2.56
8 23 -1.6 2.56
9 24 -0.6 0.36
10 24 -0.6 0.36
11 25 0.4 0.16
12 26 1.4 1.96
13 27 2.4 5.76
14 30 5.4 29.16
15 45 20.4 416.16
Jumlah 369 0.0 581.60
jkd <- sum((menit - rata2)^2)       # jumlah kuadrat deviasi
var_manual <- jkd / (n - 1)
sd_manual  <- sqrt(var_manual)

cat("Σ(x - mean)^2 =", jkd, "\n")
## Σ(x - mean)^2 = 581.6
cat("Varians (s^2) =", jkd, "/", n - 1, "=", round(var_manual, 4), "\n")
## Varians (s^2) = 581.6 / 14 = 41.5429
cat("Std. deviasi  = akar(", round(var_manual, 4), ") =", round(sd_manual, 4), "\n")
## Std. deviasi  = akar( 41.5429 ) = 6.4454

b. Verifikasi dengan RStudio

var_r <- var(menit)
sd_r  <- sd(menit)
cv    <- sd_r / rata2 * 100    # koefisien variasi (%)

kable(data.frame(
  Ukuran  = c("Varians (s²)", "Standar deviasi (s)", "Koefisien variasi (%)"),
  Manual  = c(round(var_manual, 4), round(sd_manual, 4), round(sd_manual / rata2 * 100, 2)),
  RStudio = c(round(var_r, 4), round(sd_r, 4), round(cv, 2))
), align = "c", caption = "Perbandingan hasil manual vs RStudio")
Perbandingan hasil manual vs RStudio
Ukuran Manual RStudio
Varians (s²) 41.5429 41.5429
Standar deviasi (s) 6.4454 6.4454
Koefisien variasi (%) 26.2000 26.2000

c. Apakah data bervariasi tinggi atau rendah?

Untuk menilai, digunakan koefisien variasi (CV) = s / mean × 100% dengan patokan umum: CV < 20% rendah, 20–30% sedang, > 30% tinggi.

kategori <- ifelse(cv < 20, "RENDAH", ifelse(cv <= 30, "SEDANG", "TINGGI"))

# Pembanding: tanpa pencilan
tanpa_outlier <- menit[!(menit %in% pencilan)]
sd_tanpa <- sd(tanpa_outlier)
cv_tanpa <- sd_tanpa / mean(tanpa_outlier) * 100
kategori_tanpa <- ifelse(cv_tanpa < 20, "RENDAH", ifelse(cv_tanpa <= 30, "SEDANG", "TINGGI"))

kable(data.frame(
  Kondisi = c("Semua data (n = 15)", "Tanpa pencilan (n = 14)"),
  Mean = round(c(rata2, mean(tanpa_outlier)), 2),
  SD   = round(c(sd_r, sd_tanpa), 2),
  `CV (%)` = round(c(cv, cv_tanpa), 2),
  Kategori = c(kategori, kategori_tanpa),
  check.names = FALSE
), align = "c", caption = "Penilaian tingkat variasi data")
Penilaian tingkat variasi data
Kondisi Mean SD CV (%) Kategori
Semua data (n = 15) 24.60 6.45 26.20 SEDANG
Tanpa pencilan (n = 14) 23.14 3.23 13.96 RENDAH
# Visualisasi: seberapa jauh tiap data dari mean
dev_df <- data.frame(Pengguna = data_ecotrack$Pengguna, Deviasi = menit - rata2)

ggplot(dev_df, aes(x = Pengguna, y = Deviasi, fill = Deviasi > 0)) +
  geom_col(width = 0.75, show.legend = FALSE) +
  geom_hline(yintercept = c(-sd_r, sd_r), linetype = "dashed", colour = "grey30") +
  geom_hline(yintercept = 0, colour = "black") +
  annotate("text", x = 1, y = sd_r + 1.5, label = paste0("+1 SD = ", round(sd_r, 2)),
           hjust = 0, size = 3.6) +
  annotate("text", x = 1, y = -sd_r - 1.5, label = paste0("-1 SD = -", round(sd_r, 2)),
           hjust = 0, size = 3.6) +
  scale_fill_manual(values = c("TRUE" = warna_mean, "FALSE" = warna_utama)) +
  labs(title = "Deviasi Tiap Pengguna terhadap Mean",
       subtitle = "Garis putus-putus = ±1 standar deviasi; hampir semua data berada di dalam ±1 SD kecuali P7",
       x = "Pengguna", y = "x − mean (menit)") +
  tema_ku

Kesimpulan: Varians = 41.54 dan standar deviasi = 6.45 menit (CV = 26.2%), sehingga variasi data tergolong SEDANG. Bila pencilan 45 menit dikeluarkan, SD turun menjadi 3.23 menit (CV = 14%, kategori RENDAH). Jadi, menurut saya data ini tidak bervariasi tinggi: kebiasaan pemakaian mayoritas pengguna cukup seragam, dan variasi yang tampak lebih besar terutama disebabkan oleh satu pengguna ekstrem (45 menit).


Soal 4 — Koefisien Skewness Pearson (RStudio)

a. Rumus dan Perhitungan

Karena data multimodus (modus tidak tunggal), maka digunakan Koefisien Skewness Pearson kedua yang memakai median:

\[Sk=\frac{3(\bar{x}-\text{Median})}{s}\]

sk_pearson <- 3 * (rata2 - med) / sd_r

cat("Sk = 3 x (mean - median) / s\n")
## Sk = 3 x (mean - median) / s
cat("   = 3 x (", rata2, "-", med, ") /", round(sd_r, 4), "\n")
##    = 3 x ( 24.6 - 23 ) / 6.4454
cat("   =", round(3 * (rata2 - med), 4), "/", round(sd_r, 4), "\n")
##    = 4.8 / 6.4454
cat("   =", round(sk_pearson, 4), "\n")
##    = 0.7447

b. Arah Kemencengan

arah <- ifelse(sk_pearson > 0, "MENCENG KANAN (positif)",
        ifelse(sk_pearson < 0, "MENCENG KIRI (negatif)", "SIMETRIS"))

cat("Sk Pearson =", round(sk_pearson, 4), "->", arah, "\n")
## Sk Pearson = 0.7447 -> MENCENG KANAN (positif)

c. Verifikasi dengan fungsi skewness() di R

Fungsi skewness() dari paket moments menghitung skewness berbasis momen ke-3 (rumus berbeda dari Pearson, sehingga nilainya tidak harus sama, tetapi arahnya harus sama).

sk_moments <- skewness(menit)

kable(data.frame(
  Metode = c("Pearson kedua (manual)", "skewness() paket moments"),
  Nilai  = round(c(sk_pearson, sk_moments), 4),
  Arah   = c(ifelse(sk_pearson > 0, "Positif (kanan)", "Negatif (kiri)"),
             ifelse(sk_moments > 0, "Positif (kanan)", "Negatif (kiri)"))
), align = "c", caption = "Perbandingan koefisien skewness")
Perbandingan koefisien skewness
Metode Nilai Arah
Pearson kedua (manual) 0.7447 Positif (kanan)
skewness() paket moments 2.2126 Positif (kanan)
cat("Arah kedua metode sama? ", (sign(sk_pearson) == sign(sk_moments)), "\n")
## Arah kedua metode sama?  TRUE
ggplot(data.frame(menit), aes(x = menit)) +
  geom_histogram(aes(y = after_stat(density)), binwidth = 5, boundary = 15, closed = "left",
                 fill = "#AEC6F6", colour = "white") +
  geom_density(colour = warna_utama, linewidth = 1.2, adjust = 1.2) +
  geom_vline(aes(xintercept = rata2, colour = "Mean"),   linewidth = 1.2) +
  geom_vline(aes(xintercept = med,   colour = "Median"), linewidth = 1.2, linetype = "dashed") +
  scale_colour_manual(values = c("Mean" = warna_mean, "Median" = warna_median)) +
  scale_x_continuous(breaks = seq(15, 50, 5)) +
  labs(title = "Bentuk Distribusi Data: Menceng ke Kanan",
       subtitle = paste0("Ekor panjang di sisi kanan (nilai 45)  |  Mean (", rata2,
                         ") > Median (", med, ")"),
       x = "Menit penggunaan", y = "Kepadatan", colour = NULL) +
  tema_ku +
  theme(legend.position = "top")

Interpretasi: Sk Pearson = 0.745 (> 0) dan skewness() = 2.213 (> 0), keduanya menunjukkan distribusi menceng ke kanan (positif): mayoritas pengguna berada di kisaran 18–30 menit, sedangkan sebagian kecil pengguna dengan durasi sangat lama (45 menit) membentuk ekor panjang di kanan. Hal ini konsisten dengan mean (24.6) > median (23). Nilai skewness() jauh lebih besar dari Pearson karena momen ke-3 dipangkatkan tiga sehingga sangat sensitif terhadap nilai ekstrem 45.


Soal 5 — Prosedur Mean, Median, dan Modus Data Berkelompok

Catatan: Jawaban resmi soal ini ditulis tangan di kertas sesuai instruksi. Bagian berikut hanya ringkasan prosedur sebagai pelengkap/referensi.

Misal EcoTrack memiliki data 100 pengguna dan disusun ke dalam tabel distribusi frekuensi berkelompok.

a. Menyusun tabel distribusi frekuensi

  1. Tentukan rentang (range) = data terbesar − data terkecil.
  2. Tentukan banyak kelas (k) dengan aturan Sturges: k = 1 + 3,322 log(n). Untuk n = 100, k ≈ 7,6 → dibulatkan 8 kelas (atau 7).
  3. Tentukan panjang kelas (p) = rentang / k, lalu dibulatkan ke atas.
  4. Susun kelas-kelas (batas bawah–batas atas), lalu hitung frekuensi (f) tiap kelas dengan turus.
  5. Tentukan batas kelas (tepi) = batas bawah − 0,5 dan batas atas + 0,5; titik tengah (x) = (batas bawah + batas atas)/2; serta frekuensi kumulatif (fk).

b. Menghitung ukuran pemusatan berkelompok

Notasi mengikuti modul: \(m_i\) = titik tengah kelas, \(TB\) = tepi bawah kelas, \(c\) = panjang kelas, \(F\) = frekuensi kumulatif sebelum kelas median, \(f_{Me}\) = frekuensi kelas median.

Ukuran Rumus Langkah-langkah
Mean \(\bar{x}=\dfrac{\sum f_i m_i}{\sum f_i}\) (1) Cari titik tengah \(m_i\) tiap kelas. (2) Kalikan \(f_i \cdot m_i\). (3) Jumlahkan semua \(f_i m_i\). (4) Bagi dengan \(\sum f_i = n\).
Median \(Me = TB + \left(\dfrac{\frac{n}{2}-F}{f_{Me}}\right)c\) (1) Hitung \(n/2\) = 50. (2) Buat frekuensi kumulatif, lalu cari kelas median = kelas pertama yang frekuensi kumulatifnya \(\ge n/2\). (3) Ambil \(TB\), \(F\) (frekuensi kumulatif sebelum kelas median), \(f_{Me}\), dan \(c\). (4) Masukkan ke rumus.
Modus \(Mo = L + \left(\dfrac{d_1}{d_1+d_2}\right)c\) (1) Cari kelas modus = kelas dengan frekuensi terbesar. (2) \(L\) = tepi bawah kelas modus. (3) \(d_1\) = selisih frekuensi kelas modus dengan kelas sebelumnya, \(d_2\) = selisih dengan kelas sesudahnya. (4) Masukkan ke rumus dengan \(c\) = panjang kelas.

c. Contoh visualisasi alur (opsional, ilustrasi tanpa angka)

alur <- data.frame(
  langkah = factor(c("1. Range", "2. Banyak kelas\n(Sturges)", "3. Panjang kelas",
                     "4. Tabel f, x, fk", "5. Mean, Median,\nModus"),
                   levels = c("1. Range", "2. Banyak kelas\n(Sturges)", "3. Panjang kelas",
                              "4. Tabel f, x, fk", "5. Mean, Median,\nModus")),
  urutan = 1:5
)

ggplot(alur, aes(x = urutan, y = 1)) +
  geom_segment(aes(x = 1, xend = 5, y = 1, yend = 1), colour = "grey70", linewidth = 1.5) +
  geom_point(size = 12, colour = warna_utama) +
  geom_text(aes(label = urutan), colour = "white", fontface = "bold") +
  geom_text(aes(label = langkah, y = 0.7), size = 3.6, lineheight = 0.9) +
  ylim(0.5, 1.3) +
  labs(title = "Alur Menghitung Ukuran Pemusatan Data Berkelompok") +
  theme_void() +
  theme(plot.title = element_text(face = "bold", colour = warna_utama, hjust = 0.5))


Kesimpulan Akhir

ringkasan <- data.frame(
  No = 1:4,
  Soal = c("Pemusatan data", "Kuartil & IQR", "Variasi data", "Kemencengan"),
  Hasil = c(
    paste0("Mean = ", rata2, "; Median = ", med, "; Modus = ", paste(modus, collapse = ", ")),
    paste0("Q1 = ", Q1, "; Q3 = ", Q3, "; IQR = ", IQR_val),
    paste0("Varians = ", round(var_r, 2), "; SD = ", round(sd_r, 2), "; CV = ", round(cv, 1), "% (", kategori, ")"),
    paste0("Sk Pearson = ", round(sk_pearson, 3), "; skewness() = ", round(sk_moments, 3), " (menceng kanan)")
  )
)
kable(ringkasan, align = c("c", "l", "l"), caption = "Ringkasan seluruh hasil")
Ringkasan seluruh hasil
No Soal Hasil
1 Pemusatan data Mean = 24.6; Median = 23; Modus = 22, 23, 24
2 Kuartil & IQR Q1 = 21; Q3 = 26; IQR = 5
3 Variasi data Varians = 41.54; SD = 6.45; CV = 26.2% (SEDANG)
4 Kemencengan Sk Pearson = 0.745; skewness() = 2.213 (menceng kanan)

Secara keseluruhan, mayoritas pengguna EcoTrack memakai aplikasi sekitar 23–24.6 menit per hari dengan pola yang cukup seragam. Satu pengguna dengan 45 menit adalah pencilan yang membuat distribusi menceng ke kanan dan menaikkan mean di atas median. Untuk data seperti ini, median dan IQR lebih tepat digunakan sebagai gambaran “pengguna biasa” dibandingkan mean dan standar deviasi.


## Dikerjakan oleh: Najwa Sevtia | Informatika Untirta
## Versi R: R version 4.6.1 (2026-06-24 ucrt)