Laporan ini merujuk pada data rekapitulasi (klik tautan ini).
Bahan dan Hasil lengkap analisis ini ada di drvie (klik tautan ini).
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.
# 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>
# 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)
Metodologi evaluasi dilakukan dengan pendekatan kuantitatif melalui:
# 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
# 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).
b. Heatmap Jawaban per Soal dan Peserta Untuk tampilan Heatmap lebih jelas data rekapitulasi (klik tautan ini).
Kesimpulan Berdasarkan hasil analisis statistik dan visualisasi data:
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.
# 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.
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()
# 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).
# 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
# 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)