Laporan ini merujuk pada data rekapitulasi (klik tautan ini).

Bahan dan Hasil lengkap analisis ini ada di drvie (klik tautan ini).

Latar Belakang

Pelatihan dilaksanakan untuk meningkatkan kapasitas peserta melalui pemaparan materi dan praktik langsung.
Evaluasi efektivitas pelatihan dilakukan dengan membandingkan hasil pre-test dan post-test dari 23 peserta (total 24 peserta, namun 1 peserta hanya mengikuti post-test) terhadap 14 soal yang sama.

Tujuan evaluasi ini adalah menilai sejauh mana pelatihan berdampak pada peningkatan pemahaman peserta.

1. Load Library, Autentikasi Google dan Ambil Data

# Load Library
library(googlesheets4)
## Warning: package 'googlesheets4' was built under R version 4.5.1
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.1
## 
## 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(tidyr)
## Warning: package 'tidyr' was built under R version 4.5.1
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.5.1
library(ggpubr)
## Warning: package 'ggpubr' was built under R version 4.5.1
library(purrr)
## Warning: package 'purrr' was built under R version 4.5.1
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.5.1
## 
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
## 
##     smiths
gs4_auth()  # hanya pertama kali perlu login
## ℹ Suitable tokens found in the cache, associated with these emails:
## • 'arif@planetindonesia.org'
## • 'arifdarmawannn@gmail.com'
##   Defaulting to the first email.
## ! Using an auto-discovered, cached token.
##   To suppress this message, modify your code or options to clearly consent to
##   the use of a cached token.
##   See gargle's "Non-interactive auth" vignette for more details:
##   <https://gargle.r-lib.org/articles/non-interactive-auth.html>
## ℹ The googlesheets4 package is using a cached token for
##   'arif@planetindonesia.org'.
# Link spreadsheet
sheet_url <- "https://docs.google.com/spreadsheets/d/1tMr3mKU7DXvekJapPyrK0uEy3NKmoMC-6_oit57g2eU/edit?usp=sharing"

# Baca setiap sheet
pre <- read_sheet(sheet_url, sheet = "pre-test")
## ✔ Reading from "rekapitulasi pre-post test".
## ✔ Range ''pre-test''.
post <- read_sheet(sheet_url, sheet = "post-test")
## ✔ Reading from "rekapitulasi pre-post test".
## ✔ Range ''post-test''.
questions <- read_sheet(sheet_url, sheet = "questions")
## ✔ Reading from "rekapitulasi pre-post test".
## ✔ Range ''questions''.
head(pre)
## # A tibble: 6 × 19
##    Rank Nama  `Total Score (points)` `Correct Answers` `Incorrect Answers` Q1   
##   <dbl> <chr>                  <dbl>             <dbl>               <dbl> <lis>
## 1     1 Angga                   9054                10                   4 <dbl>
## 2     2 Dean…                   8997                10                   4 <dbl>
## 3     3 Nani…                   8671                10                   4 <dbl>
## 4     4 Sigi…                   8208                10                   4 <dbl>
## 5     5 Alex…                   8183                 9                   5 <dbl>
## 6     6 Yaga…                   8042                10                   4 <dbl>
## # ℹ 13 more variables: Q2 <list>, Q3 <dbl>, Q4 <dbl>, Q5 <dbl>, Q6 <dbl>,
## #   Q7 <dbl>, Q8 <list>, Q9 <dbl>, Q10 <dbl>, Q11 <list>, Q12 <list>,
## #   Q13 <list>, Q14 <list>
head(post)
## # A tibble: 6 × 19
##    Rank Player      `Total Score (points)` `Correct Answers` `Incorrect Answers`
##   <dbl> <chr>                        <dbl>             <dbl>               <dbl>
## 1     1 Angga                        13244                14                   0
## 2     2 Sigit Sawu…                  11798                14                   0
## 3     3 Muhammad S…                  11541                13                   1
## 4     4 Wandi                        11372                13                   1
## 5     5 Guswindi                     11130                13                   1
## 6     6 Nani Siman…                  11119                12                   2
## # ℹ 14 more variables: Q1 <list>, Q2 <list>, Q3 <list>, Q4 <dbl>, Q5 <dbl>,
## #   Q6 <dbl>, Q7 <dbl>, Q8 <list>, Q9 <dbl>, Q10 <dbl>, Q11 <list>, Q12 <list>,
## #   Q13 <list>, Q14 <list>
head(questions)
## # A tibble: 6 × 7
##   question_code question_desc                answer_1 answer_2 answer_3 answer_4
##   <chr>         <chr>                        <chr>    <chr>    <chr>    <chr>   
## 1 Q1            Apa tujuan utama dari pengg… Menyusu… Meningk… Mendete… Menentu…
## 2 Q2            Dalam kerangka RBM, siapa y… Kepala … Kepala … Staf ta… Tim pem…
## 3 Q3            Dalam RBM, output SMART dap… Menyusu… Membuat… Menentu… Menetap…
## 4 Q4            SMART biasanya digunakan ol… Jumlah … Rencana… Jenis k… Aktivit…
## 5 Q5            Dalam aplikasi SMART, data … Data ik… Akta no… Informa… Data to…
## 6 Q6            Apa keuntungan dari penggun… Data le… Informa… Tidak m… Tidak m…
## # ℹ 1 more variable: correct_answers <chr>

2. Bersihkan dan Gabungkan Data

# Kita ambil nama peserta dan total skor pre vs post.

# Ambil nama dan total skor
pre_clean <- pre %>%
  select(Nama, `Total Score (points)`) %>%
  rename(Nama = Nama, PreScore = `Total Score (points)`)

post_clean <- post %>%
  select(Player, `Total Score (points)`) %>%
  rename(Nama = Player, PostScore = `Total Score (points)`)

# Gabungkan
prepost <- inner_join(pre_clean, post_clean, by = "Nama") %>%
  mutate(Selisih = PostScore - PreScore)

3. Statistik Deskriptif & Uji Signifikansi

Metodologi evaluasi dilakukan dengan pendekatan kuantitatif melalui:

  1. Uji normalitas (Shapiro-Wilk) terhadap skor pre-test dan post-test.
  2. Uji beda berpasangan menggunakan Wilcoxon Signed-Rank Test (dipilih karena skor post-test tidak terdistribusi normal).
  3. Visualisasi data berupa perbandingan skor total serta pola jawaban benar/salah per soal.
# Membandingkan total skor pre dan post test.
# Melihat perubahan skor tiap peserta.
# Visualisasi hasil pre vs post.

# Rangkuman
summary(prepost)
##      Nama              PreScore      PostScore        Selisih    
##  Length:23          Min.   :2743   Min.   : 5061   Min.   :-774  
##  Class :character   1st Qu.:5894   1st Qu.: 8331   1st Qu.:2087  
##  Mode  :character   Median :7213   Median :10433   Median :2930  
##                     Mean   :6837   Mean   : 9747   Mean   :2910  
##                     3rd Qu.:7971   3rd Qu.:11080   3rd Qu.:4012  
##                     Max.   :9054   Max.   :13244   Max.   :7784
# Uji normalitas
shapiro.test(prepost$PreScore)
## 
##  Shapiro-Wilk normality test
## 
## data:  prepost$PreScore
## W = 0.94081, p-value = 0.1871
shapiro.test(prepost$PostScore)
## 
##  Shapiro-Wilk normality test
## 
## data:  prepost$PostScore
## W = 0.89983, p-value = 0.02507
# Uji beda pasangan
# shapiro.test(...) digunakan untuk mengecek apakah data berdistribusi normal.
# Jika kedua skor pre dan post berdistribusi normal (p-value > 0.05), maka digunakan uji parametrik yaitu t.test(...).
# Jika salah satu tidak normal (p-value ≤ 0.05), maka digunakan uji non-parametrik (wilcox.test)
if (shapiro.test(prepost$PreScore)$p.value > 0.05 & shapiro.test(prepost$PostScore)$p.value > 0.05) {
  test_result <- t.test(prepost$PostScore, prepost$PreScore, paired = TRUE)
} else {
  test_result <- wilcox.test(prepost$PostScore, prepost$PreScore, paired = TRUE)
}
print(test_result)
## 
##  Wilcoxon signed rank exact test
## 
## data:  prepost$PostScore and prepost$PreScore
## V = 272, p-value = 1.669e-06
## alternative hypothesis: true location shift is not equal to 0
# Boxplot Pre-Test vs Post-Test (T-test)
# t-test ini sebaiknya tidak digunakan sebagai hasil utama karena skor post-test tidak terdistribus normal
# Data panjang untuk plot
plot_data <- prepost %>%
  pivot_longer(cols = c(PreScore, PostScore), names_to = "Waktu", values_to = "Skor")

# Boxplot
ggboxplot(plot_data, x = "Waktu", y = "Skor", color = "Waktu", palette = "jco",
          add = "jitter", title = "Perbandingan Skor Pre-Test dan Post-Test (T-test)") +
  stat_compare_means(paired = TRUE, method = "t.test")

# Pre-Test vs Post-Test (Wilcoxon)
# Siapkan Data dalam Format Panjang (Long)

# Data long untuk visualisasi
prepost_long <- prepost %>%
  select(Nama, PreScore, PostScore) %>%
  pivot_longer(cols = c(PreScore, PostScore), names_to = "Waktu", values_to = "Skor")

# Hitung Uji Wilcoxon Sekali Lagi (opsional, untuk p-value)
wilcox_result <- wilcox.test(prepost$PostScore, prepost$PreScore, paired = TRUE)
pval_text <- paste0("Wilcoxon test, p = ", signif(wilcox_result$p.value, 3))

#merubah posisi pretest sebelah kiri
prepost_long <- prepost_long %>%
  mutate(Waktu = factor(Waktu, levels = c("PreScore", "PostScore")))

# Buat Violin Plot
ggplot(prepost_long, aes(x = Waktu, y = Skor, fill = Waktu)) +
  geom_violin(trim = FALSE, alpha = 0.5) +
  geom_boxplot(width = 0.2, color = "black", outlier.shape = NA) +
  geom_jitter(width = 0.1, alpha = 0.6, color = "gray40") +
  labs(title = "Perbandingan Skor Pre-Test dan Post-Test (Wilcoxon)",
       subtitle = pval_text,
       x = "Waktu",
       y = "Skor") +
  theme_minimal(base_size = 13) +
  scale_fill_manual(values = c("PreScore" = "#F4A259", "PostScore" = "#118AB2")) +
  theme(legend.position = "none")

Hasil Uji Statistik

a. Uji Normalitas (Shapiro-Wilk) - Pre-test: W = 0.94081, p = 0.1871 → normal - Post-test: W = 0.89983, p = 0.02507 → tidak normal

Karena skor post-test tidak berdistribusi normal (p < 0.05), maka dipilih uji non-parametrik Wilcoxon Signed-Rank Test.

b. Uji Wilcoxon Signed-Rank - V = 272
- p-value = 1.669e-06 (≈ 0.00000167)

Interpretasi:
Terdapat perbedaan yang sangat signifikan antara skor pre-test dan post-test.
Dengan p < 0.001, peningkatan skor bukan karena kebetulan, melainkan karena dampak nyata pelatihan.

Rangkuman Statistik Deskriptif - Rata-rata skor pre-test: 6.837 - Rata-rata skor post-test: 9.747 - Rata-rata peningkatan skor: +2.910 poin - Peningkatan minimum: –0.774 (1 peserta menurun)
- Peningkatan maksimum: +7.784

3. Evaluasi Terhadap Pelatihan (Efektivitas)

# Heatmap Jawaban Peserta untuk Setiap Soal (Pre-test vs Post-test)
# Binerkan soal (0 = salah/NA, 1 = benar)
soal_cols <- paste0("Q", 1:14)
binerkan_fix <- function(df) {
  df %>%
    mutate(across(starts_with("Q"), 
                  ~ map_dbl(., ~ suppressWarnings(as.numeric(.))))) %>% 
    mutate(across(starts_with("Q"), ~ ifelse(is.na(.) | . == 0, 0, 1)))
}

pre_bin <- pre %>%
  select(Nama, all_of(soal_cols)) %>%
  binerkan_fix() %>%
  mutate(Tipe = "Pre-Test")

post_bin <- post %>%
  select(Player, all_of(soal_cols)) %>%
  rename(Nama = Player) %>%
  binerkan_fix() %>%
  mutate(Tipe = "Post-Test")

# Gabungkan
jawaban_bin <- bind_rows(pre_bin, post_bin)

# Pastikan urutan soal dan tipe
heatmap_data <- jawaban_bin %>%
  pivot_longer(cols = all_of(soal_cols), names_to = "Soal", values_to = "Jawaban") %>%
  mutate(
    Soal = factor(Soal, levels = paste0("Q", 1:14)), 
    Tipe = factor(Tipe, levels = c("Pre-Test", "Post-Test"))
  )

# Plot heatmap
ggplot(heatmap_data, aes(x = Soal, y = Nama, fill = factor(Jawaban))) +
  geom_tile(color = "white") +
  facet_wrap(~Tipe, ncol = 2) +  # Pre kiri, Post kanan
  scale_fill_manual(
    values = c(
      "0" = "#F4A259",  # warm sand yellow (salah)
      "1" = "#118AB2"   # ocean blue (benar)
    ),
    labels = c("Salah", "Benar")
  ) +
  labs(
    title = "Heatmap Jawaban Peserta per Soal",
    x = "Soal", y = "Peserta", fill = "Jawaban"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    panel.grid = element_blank(),
    strip.background = element_rect(fill = "#E6E2D3", color = NA),
    strip.text = element_text(color = "#3E3E3E", face = "bold")
  )

a. Boxplot dan Violin Plot (Pre-Test vs Post-Test) Untuk tampilan boxplot lebih jelas (klik tautan ini).

Untuk tampilan Violin Plot lebih jelas (klik tautan ini).

  • Sebaran nilai post-test lebih tinggi dan padat di bagian atas.
  • Median skor post-test jelas meningkat dibanding pre-test.
  • Sebagian besar titik peserta (jitter plot) menunjukkan peningkatan skor.

b. Heatmap Jawaban per Soal dan Peserta Untuk tampilan Heatmap lebih jelas data rekapitulasi (klik tautan ini).

  • Hampir seluruh peserta memperbaiki jumlah jawaban benar pada post-test.
  • Jawaban benar meningkat pada hampir semua soal, termasuk soal-soal yang semula banyak dijawab salah.
  • Hal ini menunjukkan adanya pemahaman yang lebih baik setelah pelatihan.

Kesimpulan Berdasarkan hasil analisis statistik dan visualisasi data:

  • Pelatihan terbukti efektif meningkatkan pemahaman peserta.
  • Hasil signifikan (p < 0.001) menunjukkan peningkatan nilai tidak disebabkan kebetulan.
  • Peningkatan konsisten terlihat pada skor total maupun performa tiap soal.

Rekomendasi Terhadap Pelatihan (metode, penilaian dan pemantauan) - Pelatihan serupa dapat direplikasi pada kelompok lain dengan penyesuaian konteks.
- Soal pre–post test dapat dijadikan alat ukur baku evaluasi pelatihan berikutnya.
- Perlu evaluasi lanjutan (retention test) beberapa minggu setelah pelatihan untuk menilai daya ingat jangka menengah.

4. Evaluasi Terhadap Peserta (Perubahan Individu & Soal)

  • Analisis Performa Per Soal.
  • Mengetahui soal mana yang paling sulit (banyak salah di pre-test).
  • Melihat peningkatan pemahaman pada masing-masing soal setelah pelatihan.
  • Menemukan soal yang masih sulit walaupun setelah pelatihan → bahan evaluasi materi.
# Ambil data soal dari pre-test dan post-test
pre_soal <- pre %>% select(Nama, all_of(soal_cols))
post_soal <- post %>% select(Player, all_of(soal_cols)) %>%
  rename(Nama = Player)

# Binerkan (0/1)
pre_bin <- binerkan_fix(pre_soal)
post_bin <- binerkan_fix(post_soal)

# Hitung proporsi benar
prop_pre <- colMeans(pre_bin[, soal_cols])
prop_post <- colMeans(post_bin[, soal_cols])

# Gabungkan ke dalam satu data frame
performa_soal <- tibble(
  Soal = soal_cols,
  PreTest = round(prop_pre * 100, 1),
  PostTest = round(prop_post * 100, 1),
  Peningkatan = round((prop_post - prop_pre) * 100, 1)
)

# Ambil data soal dari pre-test dan post-test
pre_soal <- pre %>% select(Nama, all_of(soal_cols))
post_soal <- post %>% select(Player, all_of(soal_cols)) %>%
  rename(Nama = Player)

# Binerkan (0/1)
pre_bin <- binerkan_fix(pre_soal)
post_bin <- binerkan_fix(post_soal)

# Hitung proporsi benar
prop_pre <- colMeans(pre_bin[, soal_cols])
prop_post <- colMeans(post_bin[, soal_cols])

# Gabungkan ke dalam satu data frame
# Pastikan performa_soal ada
performa_soal <- performa_soal %>%
  arrange(PostTest) %>%
  mutate(Soal = factor(Soal, levels = Soal)) # urutan faktor ikut PostTest

# Ubah ke format panjang
plot_data <- performa_soal %>%
  pivot_longer(cols = c("PreTest", "PostTest"),
               names_to = "Waktu",
               values_to = "Persentase")

ggplot(plot_data, aes(x = Soal, y = Persentase, fill = Waktu)) +
  geom_col(position = "dodge") +  # lebih ringkas dari geom_bar(stat="identity")
  labs(title = "Performa Soal Pre-Test vs Post-Test",
       y = "Persentase Jawaban Benar (%)",
       x = "Kode Soal") +
  theme_minimal(base_size = 13) +
  scale_fill_manual(values = c("PreTest" = "#F4A259", "PostTest" = "#118AB2"))+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Untuk tampilan Analisis Performa Per Soal lebih jelas (klik tautan ini).

Hasil Utama - Peningkatan signifikan pada hampir semua soal.
- Contoh: Q13 (10% → >40%), Q14 (20% → >90%), Q8 & Q11 meningkat >40 poin persentase.
- Soal dengan performa awal tinggi (Q1, Q4, Q7, Q9, Q10) tetap tinggi pada post-test.
- Distribusi kesulitan soal:
- Pre-test: variasi besar (10% – 90% benar).
- Post-test: lebih merata dan lebih tinggi.
- Rata-rata peningkatan: +25–30%.
- Tidak ada soal yang mengalami penurunan performa. - Visualisasi ini memperkuat temuan skor total bahwa pelatihan berhasil meningkatkan pengetahuan peserta.
- Soal sulit di pre-test menjadi lebih dikuasai pada post-test.
- Memberi umpan balik penting bagi fasilitator mengenai topik-topik yang perlu perhatian lebih.

Gap Analysis per Soal

ggplot(performa_soal, aes(x = Soal, y = Peningkatan)) +
  geom_col(fill = "#06D6A0") +
  geom_hline(yintercept = 0, linetype = "dashed") +
  labs(title = "Peningkatan Persentase Jawaban Benar per Soal",
       y = "Peningkatan (%)", x = "Kode Soal") +
  theme_minimal()

Analisis Perubahan Per Peserta

# Barplot Selisih per Peserta
ggplot(prepost, aes(x = reorder(Nama, Selisih), y = Selisih, fill = Selisih > 0)) +
  geom_col() +
  coord_flip() +
  labs(title = "Perubahan Skor per Peserta",
       y = "Selisih Skor (Post - Pre)", x = "Peserta") +
  scale_fill_manual(values = c("TRUE" = "#118AB2", "FALSE" = "#F4A259"),
                    labels = c("Turun", "Naik")) +
  theme_minimal()

Sebagian besar peserta naik (bar biru), artinya ada peningkatan pemahaman.

Namun ada juga peserta yang stagnan atau menurun (contoh: Aris Tofan Gala Bura, skor turun -774).

Ringkasan Otomatis (Top 3)

# tabel ringkasan otomatis yang langsung menunjukkan:
# 1. Top 3 peserta paling meningkat
# 2. Top 3 peserta stagnan/menurun
# 3. Top 3 soal paling sulit setelah pelatihan?
# --- 1. Top 3 peserta paling meningkat ---
top_meningkat <- prepost %>%
  arrange(desc(Selisih)) %>%
  select(Nama, PreScore, PostScore, Selisih) %>%
  head(3)

# --- 2. Top 3 peserta stagnan/menurun ---
top_stagnan <- prepost %>%
  arrange(Selisih) %>%
  select(Nama, PreScore, PostScore, Selisih) %>%
  head(3)

# --- 3. Top 3 soal paling sulit setelah pelatihan (post-test rendah) ---
soal_sulit <- performa_soal %>%
  arrange(PostTest) %>%
  head(3)

# --- 4. Gabungkan jadi list ringkasan ---
list(
  "Top 3 Peserta Paling Meningkat" = top_meningkat,
  "Top 3 Peserta Stagnan/Menurun" = top_stagnan,
  "Top 3 Soal Paling Sulit Setelah Pelatihan" = soal_sulit
)
## $`Top 3 Peserta Paling Meningkat`
## # A tibble: 3 × 4
##   Nama                   PreScore PostScore Selisih
##   <chr>                     <dbl>     <dbl>   <dbl>
## 1 Carlos Nussari Jeharut     2743     10527    7784
## 2 Galih Pancarial            5604     10723    5119
## 3 Ervinawati                 5712     10433    4721
## 
## $`Top 3 Peserta Stagnan/Menurun`
## # A tibble: 3 × 4
##   Nama                 PreScore PostScore Selisih
##   <chr>                   <dbl>     <dbl>   <dbl>
## 1 Aris Tofan Gala Bura     7312      6538    -774
## 2 Yaga Ernanda             8042      8133      91
## 3 Roky Pratama             5213      5647     434
## 
## $`Top 3 Soal Paling Sulit Setelah Pelatihan`
## # A tibble: 3 × 4
##   Soal  PreTest PostTest Peningkatan
##   <fct>   <dbl>    <dbl>       <dbl>
## 1 Q13       8.7     41.7        33  
## 2 Q8       34.8     50          15.2
## 3 Q2       78.3     62.5       -15.8
  • Top 3 Peserta Paling Meningkat: Carlos, Galih, Ervinawati → dampak pelatihan paling terasa.
  • Top 3 Peserta Stagnan/Menurun: Aris, Yaga, Roky → perlu follow-up personal.
  • Top 3 Soal Paling Sulit: Q13, Q8, Q2 → materi terkait soal ini harus ditinjau ulang.

Visualisasi Ringkasan Top 3

# 1. Visualisasi Top 3 Peserta Paling Meningkat
ggplot(top_meningkat, aes(x = reorder(Nama, Selisih), y = Selisih)) +
  geom_col(fill = "#06D6A0") +
  coord_flip() +
  labs(
    title = "Top 3 Peserta Paling Meningkat",
    x = "Peserta",
    y = "Selisih Skor (Post - Pre)"
  ) +
  theme_minimal(base_size = 13)

# 2. Visualisasi Top 3 Peserta Stagnan/Menurun
ggplot(top_stagnan, aes(x = reorder(Nama, Selisih), y = Selisih)) +
  geom_col(fill = "#EF476F") +
  coord_flip() +
  labs(
    title = "Top 3 Peserta Stagnan/Menurun",
    x = "Peserta",
    y = "Selisih Skor (Post - Pre)"
  ) +
  theme_minimal(base_size = 13)

# 3. Visualisasi Top 3 Soal Paling Sulit Setelah Pelatihan
ggplot(soal_sulit, aes(x = reorder(Soal, PostTest), y = PostTest)) +
  geom_col(fill = "#118AB2") +
  geom_text(aes(label = paste0(PostTest, "%")), hjust = -0.1, size = 4) +
  coord_flip() +
  labs(
    title = "Top 3 Soal Paling Sulit Setelah Pelatihan",
    x = "Kode Soal",
    y = "Persentase Benar di Post-Test (%)"
  ) +
  theme_minimal(base_size = 13) +
  ylim(0, 100)