# =============================================================================
# REPEATED MEASURE ANALYSIS DENGAN R - DATA EXCEL 3 KELOMPOK x 4 PENGUKURAN
#
# NAMA : VINA RAHMADANI
# NIM : 2611018027
#
# Data : data_stunting_tb_3kelompok.xlsx, sheet "Data"
# (DATA SIMULASI untuk latihan, bukan data penelitian nyata)
# Desain : 75 balita stunting dalam 3 kelompok (Kontrol, PMT, PMT+Edukasi;
# n = 25 per kelompok), tinggi badan (TB, cm) diukur 4 kali (B0-B3)
# Kolom : id, kelompok, usia_bln, jk, TB_B0, TB_B1, TB_B2, TB_B3
#
# Isi:
# 0. Paket & pengaturan
# 1. Impor data Excel (format lebar -> panjang)
# 2. Eksplorasi data: statistik deskriptif, profile plot, spaghetti plot
# 3. Repeated Measure ANOVA satu arah (within-subject: Waktu)
# 3a. Uji asumsi: outlier, normalitas, sfierisitas (Mauchly)
# 3b. ANOVA + koreksi Greenhouse-Geisser / Huynh-Feldt
# 3c. Pendekatan multivariat (MANOVA) sebagai pembanding
# 3d. Post hoc berpasangan & kontras polinomial (tren)
# 3e. Alternatif nonparametrik: uji Friedman
# 4. Mixed Design ANOVA (between: Kelompok x within: Waktu)
# 4a. Uji asumsi: outlier, normalitas, Levene, Box's M, Mauchly
# 4b. ANOVA campuran + ukuran efek
# 4c. Analisis efek sederhana (simple effects) & post hoc
# 4d. Kontras interaksi (pertambahan TB antarkelompok)
# 5. Pembanding: Linear Mixed Model (LMM) + kovariat usia & jenis kelamin
# 6. Analisis pertambahan TB (B3 - B0) dengan ANCOVA
# 7. Menyimpan output
# =============================================================================
# 0. PAKET & PENGATURAN
paket <- c("dplyr", "tidyr", "ggplot2", "afex", "emmeans", "rstatix", "car",
"effectsize", "lme4", "lmerTest", "pbkrtest", "performance", "ggpubr",
"Hmisc", "readxl")
baru <- paket[!paket %in% rownames(installed.packages())]
if (length(baru) > 0) install.packages(baru, repos = "https://cloud.r-project.org")
suppressPackageStartupMessages({
library(dplyr) # manipulasi data (menyediakan pipe %>%)
library(tidyr) # format panjang <-> lebar
library(ggplot2) # grafik
library(afex) # ANOVA within/mixed (tipe III, koreksi GG/HF, MANOVA)
library(emmeans) # rerata marginal, efek sederhana, post hoc, kontras
library(rstatix) # uji asumsi yang ramah pipe
library(car) # leveneTest, Anova
library(effectsize) # eta kuadrat parsial, omega kuadrat
library(lme4) # linear mixed model
library(lmerTest) # uji F/t dengan derajat bebas Kenward-Roger
})
options(contrasts = c("contr.sum", "contr.poly")) # kontras jumlah-nol untuk SS tipe III
afex_options(emmeans_model = "multivariate") # post hoc tahan terhadap non-sfierisitas
theme_set(theme_bw(base_size = 12))
# Pembungkus: jalankan langkah tambahan; jika galat, tampilkan pesan lalu lanjut.
coba <- function(expr) {
hasil <- try(expr, silent = TRUE)
if (inherits(hasil, "try-error")) {
message(" [dilewati] ", conditionMessage(attr(hasil, "condition")))
} else {
print(hasil)
}
invisible(hasil)
}
# 1. IMPOR DATA EXCEL
# Letakkan file Excel di working directory (cek dengan getwd(); ubah dengan setwd("folder_anda"))
# atau isi file_data dengan path lengkap, mis. "C:/Users/nama/Documents/data_stunting_tb_3kelompok.xlsx"
calon_file <- c("data_stunting_tb_3kelompok.xlsx", "data_stunting_tb_3kelompok (1).xlsx")
file_data <- calon_file[file.exists(calon_file)][1]
if (is.na(file_data)) {
if (interactive()) {
message("File Excel tidak ditemukan di: ", getwd(), "\nSilakan pilih file .xlsx secara manual.")
file_data <- file.choose()
} else {
stop("File Excel tidak ditemukan di: ", getwd(),
"\nPindahkan file ke folder tersebut atau gunakan setwd().")
}
}
message("Membaca data dari: ", file_data)
## Membaca data dari: data_stunting_tb_3kelompok.xlsx
kel_lab <- c("Kontrol", "PMT", "PMT+Edukasi")
bln_vec <- c(0, 1, 2, 3) # ASUMSI: B0-B3 = bulan ke-0 s.d. 3; ubah sesuai desain
kol_tb <- paste0("TB_B", 0:3) # nama kolom TB di file
dat_wide <- as.data.frame(readxl::read_excel(file_data, sheet = "Data"))
names(dat_wide) <- trimws(names(dat_wide))
# Pemeriksaan struktur & data hilang
stopifnot(all(c("id", "kelompok", "usia_bln", "jk", kol_tb) %in% names(dat_wide)))
# Pastikan kolom numerik terbaca sebagai angka (jaga-jaga bila desimal memakai koma)
for (k in c("usia_bln", kol_tb)) {
if (!is.numeric(dat_wide[[k]])) dat_wide[[k]] <- as.numeric(gsub(",", ".", dat_wide[[k]]))
}
dat_wide$kelompok <- trimws(dat_wide$kelompok)
dat_wide$jk <- trimws(dat_wide$jk)
print(colSums(is.na(dat_wide)))
## id kelompok usia_bln jk TB_B0 TB_B1 TB_B2 TB_B3
## 0 0 0 0 0 0 0 0
dat_wide$kelompok <- factor(dat_wide$kelompok, levels = kel_lab)
stopifnot(!any(is.na(dat_wide$kelompok))) # berhenti jika ada label kelompok tak cocok
dat_wide$jk <- factor(dat_wide$jk, levels = c("L", "P"))
dat_wide$id <- factor(dat_wide$id)
print(table(dat_wide$kelompok))
##
## Kontrol PMT PMT+Edukasi
## 25 25 25
# Format panjang (satu baris = satu pengukuran), dibutuhkan afex/rstatix/lme4
dat_long <- dat_wide %>%
pivot_longer(all_of(kol_tb), names_to = "waktu", values_to = "tb") %>%
mutate(waktu = factor(waktu, levels = kol_tb, labels = paste0("B", 0:3)),
bulan = bln_vec[as.integer(waktu)])
print(head(dat_wide))
## id kelompok usia_bln jk TB_B0 TB_B1 TB_B2 TB_B3
## 1 S001 Kontrol 12 L 68.4 69.0 70.5 70.5
## 2 S002 Kontrol 13 P 66.9 69.5 69.6 70.3
## 3 S003 Kontrol 13 L 71.0 71.0 72.2 72.6
## 4 S004 Kontrol 14 P 70.0 70.7 71.3 71.5
## 5 S005 Kontrol 15 P 70.4 71.2 72.5 73.0
## 6 S006 Kontrol 16 L 73.4 75.3 75.6 76.1
print(head(dat_long))
## # A tibble: 6 × 7
## id kelompok usia_bln jk waktu tb bulan
## <fct> <fct> <dbl> <fct> <fct> <dbl> <dbl>
## 1 S001 Kontrol 12 L B0 68.4 0
## 2 S001 Kontrol 12 L B1 69 1
## 3 S001 Kontrol 12 L B2 70.5 2
## 4 S001 Kontrol 12 L B3 70.5 3
## 5 S002 Kontrol 13 P B0 66.9 0
## 6 S002 Kontrol 13 P B1 69.5 1
str(dat_long)
## tibble [300 × 7] (S3: tbl_df/tbl/data.frame)
## $ id : Factor w/ 75 levels "S001","S002",..: 1 1 1 1 2 2 2 2 3 3 ...
## $ kelompok: Factor w/ 3 levels "Kontrol","PMT",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ usia_bln: num [1:300] 12 12 12 12 13 13 13 13 13 13 ...
## $ jk : Factor w/ 2 levels "L","P": 1 1 1 1 2 2 2 2 1 1 ...
## $ waktu : Factor w/ 4 levels "B0","B1","B2",..: 1 2 3 4 1 2 3 4 1 2 ...
## $ tb : num [1:300] 68.4 69 70.5 70.5 66.9 69.5 69.6 70.3 71 71 ...
## $ bulan : num [1:300] 0 1 2 3 0 1 2 3 0 1 ...
# 2. EKSPLORASI DATA
desk <- dat_long %>%
group_by(kelompok, waktu) %>%
get_summary_stats(tb, type = "mean_sd")
print(desk)
## # A tibble: 12 × 6
## kelompok waktu variable n mean sd
## <fct> <fct> <fct> <dbl> <dbl> <dbl>
## 1 Kontrol B0 tb 25 76.9 5.48
## 2 Kontrol B1 tb 25 77.7 5.18
## 3 Kontrol B2 tb 25 78.5 5.30
## 4 Kontrol B3 tb 25 79.2 5.32
## 5 PMT B0 tb 25 77.2 5.56
## 6 PMT B1 tb 25 78.2 5.38
## 7 PMT B2 tb 25 79.1 5.48
## 8 PMT B3 tb 25 80.1 5.33
## 9 PMT+Edukasi B0 tb 25 77.8 5.50
## 10 PMT+Edukasi B1 tb 25 78.8 5.52
## 11 PMT+Edukasi B2 tb 25 79.9 5.40
## 12 PMT+Edukasi B3 tb 25 81.0 5.46
# Kesetaraan kelompok pada baseline (usia, jenis kelamin, TB awal)
print(dat_wide %>% group_by(kelompok) %>%
get_summary_stats(usia_bln, TB_B0, type = "mean_sd"))
## # A tibble: 6 × 5
## kelompok variable n mean sd
## <fct> <fct> <dbl> <dbl> <dbl>
## 1 Kontrol usia_bln 25 23.2 7.63
## 2 Kontrol TB_B0 25 76.9 5.48
## 3 PMT usia_bln 25 23.1 7.56
## 4 PMT TB_B0 25 77.2 5.56
## 5 PMT+Edukasi usia_bln 25 23.3 7.62
## 6 PMT+Edukasi TB_B0 25 77.8 5.50
print(table(dat_wide$kelompok, dat_wide$jk))
##
## L P
## Kontrol 13 12
## PMT 8 17
## PMT+Edukasi 14 11
print(anova_test(data = dat_wide, dv = usia_bln, between = kelompok))
## ANOVA Table (type II tests)
##
## Effect DFn DFd F p p<.05 ges
## 1 kelompok 2 72 0.003 0.997 8.33e-05
print(anova_test(data = dat_wide, dv = TB_B0, between = kelompok))
## ANOVA Table (type II tests)
##
## Effect DFn DFd F p p<.05 ges
## 1 kelompok 2 72 0.181 0.835 0.005
# Matriks kovarians & korelasi antarwaktu (seluruh subjek)
S <- cov(dat_wide[, kol_tb])
R <- cor(dat_wide[, kol_tb])
print(round(S, 1)); print(round(R, 3))
## TB_B0 TB_B1 TB_B2 TB_B3
## TB_B0 29.7 28.8 29.0 28.9
## TB_B1 28.8 28.2 28.3 28.2
## TB_B2 29.0 28.3 28.7 28.5
## TB_B3 28.9 28.2 28.5 28.6
## TB_B0 TB_B1 TB_B2 TB_B3
## TB_B0 1.000 0.996 0.995 0.990
## TB_B1 0.996 1.000 0.997 0.994
## TB_B2 0.995 0.997 1.000 0.996
## TB_B3 0.990 0.994 0.996 1.000
# Varians selisih antarpasangan waktu (inti asumsi sfierisitas)
pasangan <- combn(kol_tb, 2)
var_selisih <- apply(pasangan, 2, function(p) var(dat_wide[[p[1]]] - dat_wide[[p[2]]]))
names(var_selisih) <- apply(pasangan, 2, paste, collapse = " - ")
print(round(var_selisih, 3))
## TB_B0 - TB_B1 TB_B0 - TB_B2 TB_B0 - TB_B3 TB_B1 - TB_B2 TB_B1 - TB_B3
## 0.271 0.319 0.578 0.192 0.361
## TB_B2 - TB_B3
## 0.241
# Profile plot: rerata dan 95% CI per kelompok (mean_cl_normal memerlukan paket Hmisc)
p_profil <- ggplot(dat_long, aes(bulan, tb, colour = kelompok, group = kelompok)) +
stat_summary(fun = mean, geom = "line", linewidth = 1) +
stat_summary(fun = mean, geom = "point", size = 2.5) +
stat_summary(fun.data = mean_cl_normal, geom = "errorbar", width = .1) +
scale_x_continuous(breaks = bln_vec, labels = paste0("B", 0:3)) +
labs(x = "Waktu pengukuran", y = "Tinggi badan (cm)", colour = "Kelompok",
title = "Profil rerata TB (dengan 95% CI)") +
theme(legend.position = "bottom")
print(p_profil)

# Spaghetti plot: lintasan tiap anak
p_spag <- ggplot(dat_long, aes(bulan, tb, group = id)) +
geom_line(alpha = .3) +
stat_summary(aes(group = kelompok), fun = mean, geom = "line",
colour = "firebrick", linewidth = 1.2) +
facet_wrap(~ kelompok) +
scale_x_continuous(breaks = bln_vec, labels = paste0("B", 0:3)) +
labs(x = "Waktu pengukuran", y = "TB (cm)", title = "Lintasan individu dan rerata kelompok")
print(p_spag)

# 3. REPEATED MEASURE ANOVA SATU ARAH
# Pertanyaan: apakah TB berubah selama pengukuran pada kelompok PMT+Edukasi?
# (ganti dengan "PMT" atau "Kontrol" untuk kelompok lain)
d1 <- droplevels(dplyr::filter(dat_long, kelompok == "PMT+Edukasi"))
d1w <- dplyr::filter(dat_wide, kelompok == "PMT+Edukasi")
## 3a. Uji asumsi -------------------------------------------------------------
# (i) Outlier per waktu (ekstrem = di luar Q1-3IQR / Q3+3IQR)
print(d1 %>% group_by(waktu) %>% identify_outliers(tb))
## [1] waktu id kelompok usia_bln jk tb bulan
## [8] is.outlier is.extreme
## <0 rows> (or 0-length row.names)
# (ii) Normalitas per waktu (Shapiro-Wilk) dan Q-Q plot
print(d1 %>% group_by(waktu) %>% shapiro_test(tb))
## # A tibble: 4 × 4
## waktu variable statistic p
## <fct> <chr> <dbl> <dbl>
## 1 B0 tb 0.951 0.262
## 2 B1 tb 0.951 0.259
## 3 B2 tb 0.958 0.370
## 4 B3 tb 0.952 0.285
print(ggpubr::ggqqplot(d1, "tb", facet.by = "waktu"))

# (iii) Sfierisitas: Mauchly (dilaporkan otomatis oleh anova_test & afex)
aov1_rs <- anova_test(data = d1, dv = tb, wid = id, within = waktu,
effect.size = "pes")
print(aov1_rs) # ANOVA, Mauchly, koreksi GG & HF
## ANOVA Table (type III tests)
##
## $ANOVA
## Effect DFn DFd F p p<.05 pes
## 1 waktu 3 72 353.278 5.61e-43 * 0.936
##
## $`Mauchly's Test for Sphericity`
## Effect W p p<.05
## 1 waktu 0.481 0.005 *
##
## $`Sphericity Corrections`
## Effect GGe DF[GG] p[GG] p[GG]<.05 HFe DF[HF] p[HF]
## 1 waktu 0.656 1.97, 47.26 5.05e-29 * 0.715 2.14, 51.45 2.18e-31
## p[HF]<.05
## 1 *
print(get_anova_table(aov1_rs, correction = "auto")) # GG dipakai jika Mauchly p < .05
## ANOVA Table (type III tests)
##
## Effect DFn DFd F p p<.05 pes
## 1 waktu 1.97 47.26 353.278 5.05e-29 * 0.936
## 3b. ANOVA dengan afex (sumber utama laporan) -------------------------------
aov1 <- aov_ez(id = "id", dv = "tb", data = d1, within = "waktu",
anova_table = list(es = c("ges", "pes"), correction = "GG"))
print(aov1)
## Anova Table (Type 3 tests)
##
## Response: tb
## Effect df MSE F ges pes p.value
## 1 waktu 1.97, 47.26 0.20 353.28 *** .047 .936 <.001
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
##
## Sphericity correction method: GG
print(summary(aov1)) # univariat tanpa koreksi + Mauchly + epsilon GG & HF
##
## Univariate Type III Repeated-Measures ANOVA Assuming Sphericity
##
## Sum Sq num Df Error SS den Df F value Pr(>F)
## (Intercept) 629976 1 2865.36 24 5276.62 < 2.2e-16 ***
## waktu 140 3 9.53 72 353.28 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## Mauchly Tests for Sphericity
##
## Test statistic p-value
## waktu 0.48114 0.0053176
##
##
## Greenhouse-Geisser and Huynh-Feldt Corrections
## for Departure from Sphericity
##
## GG eps Pr(>F[GG])
## waktu 0.65638 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## HF eps Pr(>F[HF])
## waktu 0.7145845 2.175399e-31
# Ukuran efek tambahan
coba(eta_squared(aov1, partial = TRUE))
## # Effect Size for ANOVA (Type III)
##
## Parameter | Eta2 (partial) | 95% CI
## -----------------------------------------
## waktu | 0.94 | [0.91, 1.00]
##
## - One-sided CIs: upper bound fixed at [1.00].
coba(omega_squared(aov1, partial = TRUE))
## # Effect Size for ANOVA (Type III)
##
## Parameter | Omega2 (partial) | 95% CI
## -------------------------------------------
## waktu | 0.04 | [0.00, 1.00]
##
## - One-sided CIs: upper bound fixed at [1.00].
## 3c. Pendekatan multivariat (tidak memerlukan sfierisitas) ------------------
coba(aov1$Anova) # Pillai, Wilks, Hotelling-Lawley, Roy
##
## Type III Repeated Measures MANOVA Tests: Pillai test statistic
## Df test stat approx F num Df den Df Pr(>F)
## (Intercept) 1 0.99547 5276.6 1 24 < 2.2e-16 ***
## waktu 1 0.95850 169.4 3 22 2.383e-15 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 3d. Post hoc & kontras tren ------------------------------------------------
em1 <- emmeans(aov1, ~ waktu)
print(em1)
## waktu emmean SE df lower.CL upper.CL
## B0 77.8 1.10 24 75.6 80.1
## B1 78.8 1.10 24 76.5 81.1
## B2 79.9 1.08 24 77.7 82.1
## B3 81.0 1.09 24 78.7 83.2
##
## Confidence level used: 0.95
print(pairs(em1, adjust = "bonferroni")) # semua pasangan waktu (6)
## contrast estimate SE df t.ratio p.value
## B0 - B1 -0.944 0.0887 24 -10.642 <0.0001
## B0 - B2 -2.052 0.1120 24 -18.400 <0.0001
## B0 - B3 -3.160 0.1420 24 -22.270 <0.0001
## B1 - B2 -1.108 0.0816 24 -13.573 <0.0001
## B1 - B3 -2.216 0.1000 24 -22.062 <0.0001
## B2 - B3 -1.108 0.0798 24 -13.889 <0.0001
##
## P value adjustment: bonferroni method for 6 tests
print(contrast(em1, "trt.vs.ctrl", ref = 1, adjust = "holm")) # tiap waktu vs B0
## contrast estimate SE df t.ratio p.value
## B1 - B0 0.944 0.0887 24 10.642 <0.0001
## B2 - B0 2.052 0.1120 24 18.400 <0.0001
## B3 - B0 3.160 0.1420 24 22.270 <0.0001
##
## P value adjustment: holm method for 3 tests
print(contrast(em1, "poly")) # tren linear, kuadratik, kubik
## contrast estimate SE df t.ratio p.value
## linear 10.588 0.4610 24 22.955 <0.0001
## quadratic 0.164 0.0998 24 1.643 0.1134
## cubic -0.164 0.2350 24 -0.698 0.4920
## 3e. Alternatif nonparametrik ------------------------------------------------
print(friedman_test(d1, tb ~ waktu | id))
## # A tibble: 1 × 6
## .y. n statistic df p method
## * <chr> <int> <dbl> <dbl> <dbl> <chr>
## 1 tb 25 73.8 3 6.40e-16 Friedman test
print(friedman_effsize(d1, tb ~ waktu | id)) # Kendall's W
## # A tibble: 1 × 5
## .y. n effsize method magnitude
## * <chr> <int> <dbl> <chr> <ord>
## 1 tb 25 0.985 Kendall W large
print(d1 %>% wilcox_test(tb ~ waktu, paired = TRUE, p.adjust.method = "bonferroni"))
## # A tibble: 6 × 9
## .y. group1 group2 n1 n2 statistic p p.adj p.adj.signif
## * <chr> <chr> <chr> <int> <int> <dbl> <dbl> <dbl> <chr>
## 1 tb B0 B1 25 25 1 0.000000119 7.15e-7 ****
## 2 tb B0 B2 25 25 0 0.0000000596 3.58e-7 ****
## 3 tb B0 B3 25 25 0 0.0000000596 3.58e-7 ****
## 4 tb B1 B2 25 25 0 0.0000000596 3.58e-7 ****
## 5 tb B1 B3 25 25 0 0.0000000596 3.58e-7 ****
## 6 tb B2 B3 25 25 0 0.0000000596 3.58e-7 ****
# (Opsional) ANOVA robust berbasis trimmed mean -- paket WRS2
if (requireNamespace("WRS2", quietly = TRUE)) {
coba(WRS2::rmanova(d1$tb, d1$waktu, d1$id, tr = 0.2))
}
## Call:
## WRS2::rmanova(y = d1$tb, groups = d1$waktu, blocks = d1$id, tr = 0.2)
##
## Test statistic: F = 121.4877
## Degrees of freedom 1: 1.65
## Degrees of freedom 2: 23.06
## p-value: 0
# 4. MIXED DESIGN ANOVA (Kelompok [between] x Waktu [within])
# Pertanyaan: apakah pola pertambahan TB berbeda antarkelompok intervensi?
## 4a. Uji asumsi -------------------------------------------------------------
# (i) Outlier per sel
print(dat_long %>% group_by(kelompok, waktu) %>% identify_outliers(tb))
## [1] kelompok waktu id usia_bln jk tb bulan
## [8] is.outlier is.extreme
## <0 rows> (or 0-length row.names)
# (ii) Normalitas per sel (3 x 4 = 12 sel) dan Q-Q plot
print(dat_long %>% group_by(kelompok, waktu) %>% shapiro_test(tb))
## # A tibble: 12 × 5
## kelompok waktu variable statistic p
## <fct> <fct> <chr> <dbl> <dbl>
## 1 Kontrol B0 tb 0.950 0.252
## 2 Kontrol B1 tb 0.939 0.144
## 3 Kontrol B2 tb 0.937 0.126
## 4 Kontrol B3 tb 0.946 0.205
## 5 PMT B0 tb 0.967 0.559
## 6 PMT B1 tb 0.965 0.525
## 7 PMT B2 tb 0.964 0.506
## 8 PMT B3 tb 0.969 0.619
## 9 PMT+Edukasi B0 tb 0.951 0.262
## 10 PMT+Edukasi B1 tb 0.951 0.259
## 11 PMT+Edukasi B2 tb 0.958 0.370
## 12 PMT+Edukasi B3 tb 0.952 0.285
print(ggpubr::ggqqplot(dat_long, "tb", ggtheme = theme_bw()) +
facet_grid(waktu ~ kelompok))

# (iii) Homogenitas varians antarkelompok pada TIAP waktu (Levene)
print(dat_long %>% group_by(waktu) %>% levene_test(tb ~ kelompok))
## # A tibble: 4 × 5
## waktu df1 df2 statistic p
## <fct> <int> <int> <dbl> <dbl>
## 1 B0 2 72 0.00155 0.998
## 2 B1 2 72 0.0395 0.961
## 3 B2 2 72 0.00856 0.991
## 4 B3 2 72 0.00783 0.992
# (iv) Homogenitas matriks kovarians antarkelompok (Box's M; uji pada alpha = .001)
coba(box_m(dat_wide[, kol_tb], dat_wide$kelompok))
## # A tibble: 1 × 4
## statistic p.value parameter method
## <dbl> <dbl> <dbl> <chr>
## 1 16.6 0.678 20 Box's M-test for Homogeneity of Covariance Matric…
# (v) Sfierisitas: Mauchly (dari summary model di bawah)
## 4b. ANOVA campuran ---------------------------------------------------------
aov2 <- aov_ez(id = "id", dv = "tb", data = dat_long,
between = "kelompok", within = "waktu",
anova_table = list(es = c("ges", "pes"), correction = "GG"))
print(aov2)
## Anova Table (Type 3 tests)
##
## Response: tb
## Effect df MSE F ges pes p.value
## 1 kelompok 2, 72 116.72 0.37 .010 .010 .689
## 2 waktu 2.49, 179.01 0.17 752.58 *** .036 .913 <.001
## 3 kelompok:waktu 4.97, 179.01 0.17 7.21 *** <.001 .167 <.001
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
##
## Sphericity correction method: GG
print(summary(aov2)) # Mauchly, epsilon GG/HF, p terkoreksi
##
## Univariate Type III Repeated-Measures ANOVA Assuming Sphericity
##
## Sum Sq num Df Error SS den Df F value Pr(>F)
## (Intercept) 1857934 1 8403.8 72 15917.8949 < 2.2e-16 ***
## kelompok 87 2 8403.8 72 0.3748 0.6888
## waktu 316 3 30.2 216 752.5845 < 2.2e-16 ***
## kelompok:waktu 6 6 30.2 216 7.2059 5.056e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## Mauchly Tests for Sphericity
##
## Test statistic p-value
## waktu 0.74759 0.0009762
## kelompok:waktu 0.74759 0.0009762
##
##
## Greenhouse-Geisser and Huynh-Feldt Corrections
## for Departure from Sphericity
##
## GG eps Pr(>F[GG])
## waktu 0.82876 < 2.2e-16 ***
## kelompok:waktu 0.82876 3.775e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## HF eps Pr(>F[HF])
## waktu 0.8607309 1.493665e-98
## kelompok:waktu 0.8607309 2.591159e-06
coba(aov2$Anova) # uji multivariat untuk efek within & interaksi
##
## Type III Repeated Measures MANOVA Tests: Pillai test statistic
## Df test stat approx F num Df den Df Pr(>F)
## (Intercept) 1 0.99550 15917.9 1 72 < 2.2e-16 ***
## kelompok 2 0.01030 0.4 2 72 0.6887510
## waktu 1 0.95270 470.0 3 70 < 2.2e-16 ***
## kelompok:waktu 2 0.30488 4.3 6 142 0.0005658 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Versi rstatix (hasil identik; format ringkas untuk laporan)
aov2_rs <- anova_test(data = dat_long, dv = tb, wid = id,
between = kelompok, within = waktu, effect.size = "pes",
type = 3)
print(get_anova_table(aov2_rs, correction = "GG"))
## ANOVA Table (type III tests)
##
## Effect DFn DFd F p p<.05 pes
## 1 kelompok 2.00 72.00 0.375 6.89e-01 0.010
## 2 waktu 2.49 179.01 752.584 5.37e-95 * 0.913
## 3 kelompok:waktu 4.97 179.01 7.206 3.77e-06 * 0.167
# Ukuran efek
coba(eta_squared(aov2, partial = TRUE))
## # Effect Size for ANOVA (Type III)
##
## Parameter | Eta2 (partial) | 95% CI
## ----------------------------------------------
## kelompok | 0.01 | [0.00, 1.00]
## waktu | 0.91 | [0.90, 1.00]
## kelompok:waktu | 0.17 | [0.08, 1.00]
##
## - One-sided CIs: upper bound fixed at [1.00].
coba(omega_squared(aov2, partial = TRUE))
## # Effect Size for ANOVA (Type III)
##
## Parameter | Omega2 (partial) | 95% CI
## ------------------------------------------------
## kelompok | 0.00 | [0.00, 1.00]
## waktu | 0.04 | [0.00, 1.00]
## kelompok:waktu | 6.09e-04 | [0.00, 1.00]
##
## - One-sided CIs: upper bound fixed at [1.00].
# Plot interaksi dari model (data_geom = geom_point agar tidak butuh ggbeeswarm)
coba(afex_plot(aov2, x = "waktu", trace = "kelompok", error = "within",
mapping = c("colour", "shape", "linetype"),
data_geom = ggplot2::geom_point, data_alpha = .25) +
labs(y = "TB (cm)", x = "Waktu"))
## Warning: Panel(s) show a mixed within-between-design.
## Error bars do not allow comparisons across all means.
## Suppress error bars with: error = "none"

## 4c. Efek sederhana (bila interaksi signifikan) -----------------------------
em2 <- emmeans(aov2, ~ waktu | kelompok)
# Efek WAKTU di dalam tiap kelompok (uji F gabungan per kelompok)
coba(joint_tests(aov2, by = "kelompok"))
## Warning in pf(conf$F.ratio, conf$df1, conf$df2, lower.tail = FALSE): NaNs
## produced
## kelompok = Kontrol:
## model term df1 df2 F.ratio p.value
## waktu 3 72 111.449 <0.0001
##
## kelompok = PMT:
## model term df1 df2 F.ratio p.value
## waktu 3 72 165.173 <0.0001
##
## kelompok = PMT+Edukasi:
## model term df1 df2 F.ratio p.value
## waktu 3 72 216.700 <0.0001
# Efek KELOMPOK pada tiap waktu
coba(joint_tests(aov2, by = "waktu"))
## waktu = B0:
## model term df1 df2 F.ratio p.value
## kelompok 2 72 0.181 0.8346
##
## waktu = B1:
## model term df1 df2 F.ratio p.value
## kelompok 2 72 0.273 0.7619
##
## waktu = B2:
## model term df1 df2 F.ratio p.value
## kelompok 2 72 0.427 0.6540
##
## waktu = B3:
## model term df1 df2 F.ratio p.value
## kelompok 2 72 0.727 0.4869
# Post hoc: tiap waktu vs B0 di dalam tiap kelompok
print(contrast(em2, "trt.vs.ctrl", ref = 1, adjust = "holm"))
## kelompok = Kontrol:
## contrast estimate SE df t.ratio p.value
## B1 - B0 0.752 0.103 72 7.282 <0.0001
## B2 - B0 1.572 0.107 72 14.662 <0.0001
## B3 - B0 2.256 0.134 72 16.836 <0.0001
##
## kelompok = PMT:
## contrast estimate SE df t.ratio p.value
## B1 - B0 1.004 0.103 72 9.723 <0.0001
## B2 - B0 1.860 0.107 72 17.348 <0.0001
## B3 - B0 2.836 0.134 72 21.165 <0.0001
##
## kelompok = PMT+Edukasi:
## contrast estimate SE df t.ratio p.value
## B1 - B0 0.944 0.103 72 9.142 <0.0001
## B2 - B0 2.052 0.107 72 19.138 <0.0001
## B3 - B0 3.160 0.134 72 23.583 <0.0001
##
## P value adjustment: holm method for 3 tests
# Post hoc: perbandingan antarkelompok pada tiap waktu
em2b <- emmeans(aov2, ~ kelompok | waktu)
print(pairs(em2b, adjust = "tukey"))
## waktu = B0:
## contrast estimate SE df t.ratio p.value
## Kontrol - PMT -0.340 1.56 72 -0.218 0.9742
## Kontrol - (PMT+Edukasi) -0.928 1.56 72 -0.595 0.8233
## PMT - (PMT+Edukasi) -0.588 1.56 72 -0.377 0.9247
##
## waktu = B1:
## contrast estimate SE df t.ratio p.value
## Kontrol - PMT -0.592 1.52 72 -0.390 0.9196
## Kontrol - (PMT+Edukasi) -1.120 1.52 72 -0.738 0.7415
## PMT - (PMT+Edukasi) -0.528 1.52 72 -0.348 0.9354
##
## waktu = B2:
## contrast estimate SE df t.ratio p.value
## Kontrol - PMT -0.628 1.53 72 -0.411 0.9110
## Kontrol - (PMT+Edukasi) -1.408 1.53 72 -0.922 0.6279
## PMT - (PMT+Edukasi) -0.780 1.53 72 -0.511 0.8662
##
## waktu = B3:
## contrast estimate SE df t.ratio p.value
## Kontrol - PMT -0.920 1.52 72 -0.606 0.8176
## Kontrol - (PMT+Edukasi) -1.832 1.52 72 -1.206 0.4537
## PMT - (PMT+Edukasi) -0.912 1.52 72 -0.600 0.8204
##
## P value adjustment: tukey method for comparing a family of 3 estimates
## 4d. Kontras interaksi -------------------------------------------------------
# Apakah pertambahan TB (B3 - B0) berbeda antarkelompok?
# Langkah 1: pertambahan TB (B3 - B0) di tiap kelompok.
gain_k <- contrast(em2, list("B3-B0" = c(-1, 0, 0, 1)))
print(gain_k)
## kelompok = Kontrol:
## contrast estimate SE df t.ratio p.value
## B3-B0 2.26 0.134 72 16.836 <0.0001
##
## kelompok = PMT:
## contrast estimate SE df t.ratio p.value
## B3-B0 2.84 0.134 72 21.165 <0.0001
##
## kelompok = PMT+Edukasi:
## contrast estimate SE df t.ratio p.value
## B3-B0 3.16 0.134 72 23.583 <0.0001
print(confint(gain_k))
## kelompok = Kontrol:
## contrast estimate SE df lower.CL upper.CL
## B3-B0 2.26 0.134 72 1.99 2.52
##
## kelompok = PMT:
## contrast estimate SE df lower.CL upper.CL
## B3-B0 2.84 0.134 72 2.57 3.10
##
## kelompok = PMT+Edukasi:
## contrast estimate SE df lower.CL upper.CL
## B3-B0 3.16 0.134 72 2.89 3.43
##
## Confidence level used: 0.95
# Langkah 2: bandingkan pertambahan tersebut antarkelompok (koreksi Holm).
print(pairs(gain_k, by = NULL, adjust = "holm"))
## contrast estimate SE df t.ratio p.value
## (B3-B0 Kontrol) - (B3-B0 PMT) -0.580 0.189 72 -3.061 0.0062
## (B3-B0 Kontrol) - (B3-B0 PMT+Edukasi) -0.904 0.189 72 -4.770 <0.0001
## (B3-B0 PMT) - (B3-B0 PMT+Edukasi) -0.324 0.189 72 -1.710 0.0916
##
## P value adjustment: holm method for 3 tests
# Laju pertambahan TB (kemiringan linear, cm/bulan; ASUMSI jarak waktu sama = 1 bulan)
lin_k <- contrast(em2, list("slope_cm_per_bulan" = c(-.3, -.1, .1, .3)))
print(lin_k)
## kelompok = Kontrol:
## contrast estimate SE df t.ratio p.value
## slope_cm_per_bulan 0.759 0.0424 72 17.914 <0.0001
##
## kelompok = PMT:
## contrast estimate SE df t.ratio p.value
## slope_cm_per_bulan 0.936 0.0424 72 22.107 <0.0001
##
## kelompok = PMT+Edukasi:
## contrast estimate SE df t.ratio p.value
## slope_cm_per_bulan 1.059 0.0424 72 24.997 <0.0001
print(pairs(lin_k, by = NULL, adjust = "holm")) # apakah laju berbeda antarkelompok?
## contrast estimate SE
## slope_cm_per_bulan Kontrol - slope_cm_per_bulan PMT -0.178 0.0599
## slope_cm_per_bulan Kontrol - (slope_cm_per_bulan PMT+Edukasi) -0.300 0.0599
## slope_cm_per_bulan PMT - (slope_cm_per_bulan PMT+Edukasi) -0.122 0.0599
## df t.ratio p.value
## 72 -2.965 0.0082
## 72 -5.008 <0.0001
## 72 -2.043 0.0447
##
## P value adjustment: holm method for 3 tests
# Tren polinomial per kelompok (linear, kuadratik, kubik)
print(contrast(em2, "poly"))
## kelompok = Kontrol:
## contrast estimate SE df t.ratio p.value
## linear 7.588 0.424 72 17.914 <0.0001
## quadratic -0.068 0.130 72 -0.523 0.6025
## cubic -0.204 0.268 72 -0.760 0.4497
##
## kelompok = PMT:
## contrast estimate SE df t.ratio p.value
## linear 9.364 0.424 72 22.107 <0.0001
## quadratic -0.028 0.130 72 -0.215 0.8301
## cubic 0.268 0.268 72 0.999 0.3213
##
## kelompok = PMT+Edukasi:
## contrast estimate SE df t.ratio p.value
## linear 10.588 0.424 72 24.997 <0.0001
## quadratic 0.164 0.130 72 1.261 0.2112
## cubic -0.164 0.268 72 -0.611 0.5431
# 5. PEMBANDING: LINEAR MIXED MODEL (LMM)
# Tidak mensyaratkan sfierisitas dan menampung data hilang (MAR).
# lmm3 menambah usia (dipusatkan) dan jenis kelamin sebagai kovariat, karena
# TB sangat dipengaruhi usia dan kelompok bisa berbeda usia pada baseline.
dat_long$usia_c <- dat_long$usia_bln - mean(dat_wide$usia_bln) # usia dipusatkan
lmm1 <- lmer(tb ~ kelompok * waktu + (1 | id), data = dat_long, REML = TRUE)
lmm2 <- lmer(tb ~ kelompok * waktu + (1 + bulan | id), data = dat_long, REML = TRUE,
control = lmerControl(optimizer = "bobyqa"))
coba(anova(lmm1, lmm2, refit = FALSE)) # uji rasio kemungkinan struktur acak
## Data: dat_long
## Models:
## lmm1: tb ~ kelompok * waktu + (1 | id)
## lmm2: tb ~ kelompok * waktu + (1 + bulan | id)
## npar AIC BIC logLik -2*log(L) Chisq Df Pr(>Chisq)
## lmm1 14 819.03 870.88 -395.52 791.03
## lmm2 16 802.86 862.12 -385.43 770.86 20.167 2 4.176e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
coba(anova(lmm2, ddf = "Kenward-Roger")) # uji F tipe III efek tetap
## Type III Analysis of Variance Table with Kenward-Roger's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## kelompok 0.073 0.037 2 72.00 0.3748 0.6887508
## waktu 137.868 45.956 3 153.23 467.1471 < 2.2e-16 ***
## kelompok:waktu 2.845 0.474 6 170.40 4.8134 0.0001457 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
coba(performance::icc(lmm1)) # korelasi intrakelas
## # Intraclass Correlation Coefficient
##
## Adjusted ICC: 0.995
## Unadjusted ICC: 0.951
lmm3 <- lmer(tb ~ kelompok * waktu + usia_c + jk + (1 + bulan | id),
data = dat_long, REML = TRUE,
control = lmerControl(optimizer = "bobyqa"))
coba(anova(lmm3, ddf = "Kenward-Roger"))
## Type III Analysis of Variance Table with Kenward-Roger's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## kelompok 1.315 0.658 2 70.258 6.7227 0.0021308 **
## waktu 137.868 45.956 3 153.227 467.1471 < 2.2e-16 ***
## usia_c 137.801 137.801 1 70.000 1408.5559 < 2.2e-16 ***
## jk 3.773 3.773 1 70.000 38.5687 3.319e-08 ***
## kelompok:waktu 2.845 0.474 6 170.399 4.8134 0.0001457 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
print(summary(lmm3))
## Linear mixed model fit by REML. t-tests use Satterthwaite's method [
## lmerModLmerTest]
## Formula: tb ~ kelompok * waktu + usia_c + jk + (1 + bulan | id)
## Data: dat_long
## Control: lmerControl(optimizer = "bobyqa")
##
## REML criterion at convergence: 558.3
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -2.83439 -0.46382 0.00244 0.50915 2.70801
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## id (Intercept) 1.28095 1.1318
## bulan 0.02529 0.1590 0.21
## Residual 0.09783 0.3128
## Number of obs: 300, groups: id, 75
##
## Fixed effects:
## Estimate Std. Error df t value Pr(>|t|)
## (Intercept) 78.75421 0.14067 69.56597 559.860 < 2e-16 ***
## kelompok1 -0.72162 0.19906 69.58189 -3.625 0.000546 ***
## kelompok2 0.27311 0.20257 70.01500 1.348 0.181935
## waktu1 -1.36967 0.04168 115.09906 -32.864 < 2e-16 ***
## waktu2 -0.46967 0.03260 185.09393 -14.408 < 2e-16 ***
## waktu3 0.45833 0.03260 185.09393 14.060 < 2e-16 ***
## usia_c 0.68687 0.01805 69.99998 38.063 < 2e-16 ***
## jk1 0.86812 0.13783 69.99998 6.298 2.31e-08 ***
## kelompok1:waktu1 0.22467 0.05894 115.09906 3.812 0.000223 ***
## kelompok2:waktu1 -0.05533 0.05894 115.09906 -0.939 0.349794
## kelompok1:waktu2 0.07667 0.04610 185.09393 1.663 0.097994 .
## kelompok2:waktu2 0.04867 0.04610 185.09393 1.056 0.292492
## kelompok1:waktu3 -0.03133 0.04610 185.09393 -0.680 0.497555
## kelompok2:waktu3 -0.02333 0.04610 185.09393 -0.506 0.613356
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation matrix not shown by default, as p = 14 > 12.
## Use print(summary(lmm3), correlation=TRUE) or
## vcov(summary(lmm3)) if you need it
# Diagnostik residual LMM (normalitas & homogenitas)
par(mfrow = c(1, 3))
qqnorm(resid(lmm2), main = "Q-Q residual"); qqline(resid(lmm2))
qqnorm(ranef(lmm2)$id[, 1], main = "Q-Q intersep acak"); qqline(ranef(lmm2)$id[, 1])
plot(fitted(lmm2), resid(lmm2), xlab = "Nilai prediksi", ylab = "Residual",
main = "Residual vs prediksi"); abline(h = 0, lty = 2)

par(mfrow = c(1, 1))
# 6. PERTAMBAHAN TB (B3 - B0) DENGAN ANCOVA
# CATATAN: TB_B0 dan usia_bln berkorelasi sangat tinggi (r ~ 0,96 pada data ini), jadi jangan
# dimasukkan bersamaan dalam satu model (multikolinearitas). Dua model terpisah:
dat_wide$gain <- dat_wide$TB_B3 - dat_wide$TB_B0
print(dat_wide %>% group_by(kelompok) %>% get_summary_stats(gain, type = "mean_sd"))
## # A tibble: 3 × 5
## kelompok variable n mean sd
## <fct> <fct> <dbl> <dbl> <dbl>
## 1 Kontrol gain 25 2.26 0.638
## 2 PMT gain 25 2.84 0.66
## 3 PMT+Edukasi gain 25 3.16 0.709
print(cor(dat_wide$usia_bln, dat_wide$TB_B0))
## [1] 0.9631404
# Model A: koreksi TB baseline
m_a <- lm(gain ~ TB_B0 + jk + kelompok, data = dat_wide)
print(car::Anova(m_a, type = 3))
## Anova Table (Type III tests)
##
## Response: gain
## Sum Sq Df F value Pr(>F)
## (Intercept) 9.0833 1 21.3492 1.696e-05 ***
## TB_B0 1.9785 1 4.6503 0.03448 *
## jk 0.1617 1 0.3801 0.53957
## kelompok 11.0879 2 13.0305 1.546e-05 ***
## Residuals 29.7823 70
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
print(pairs(emmeans(m_a, ~ kelompok), adjust = "tukey"))
## contrast estimate SE df t.ratio p.value
## Kontrol - PMT -0.571 0.187 70 -3.046 0.0091
## Kontrol - (PMT+Edukasi) -0.937 0.185 70 -5.063 <0.0001
## PMT - (PMT+Edukasi) -0.366 0.188 70 -1.943 0.1343
##
## Results are averaged over the levels of: jk
## P value adjustment: tukey method for comparing a family of 3 estimates
# Model B: koreksi usia
m_b <- lm(gain ~ usia_bln + jk + kelompok, data = dat_wide)
print(car::Anova(m_b, type = 3))
## Anova Table (Type III tests)
##
## Response: gain
## Sum Sq Df F value Pr(>F)
## (Intercept) 74.396 1 175.6857 < 2.2e-16 ***
## usia_bln 2.118 1 5.0026 0.0285 *
## jk 0.400 1 0.9450 0.3343
## kelompok 10.555 2 12.4633 2.343e-05 ***
## Residuals 29.642 70
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
print(pairs(emmeans(m_b, ~ kelompok), adjust = "tukey"))
## contrast estimate SE df t.ratio p.value
## Kontrol - PMT -0.549 0.187 70 -2.942 0.0121
## Kontrol - (PMT+Edukasi) -0.913 0.184 70 -4.956 <0.0001
## PMT - (PMT+Edukasi) -0.364 0.188 70 -1.937 0.1359
##
## Results are averaged over the levels of: jk
## P value adjustment: tukey method for comparing a family of 3 estimates
# Diagnostik residual model A
par(mfrow = c(1, 2))
qqnorm(resid(m_a), main = "Q-Q residual"); qqline(resid(m_a))
plot(fitted(m_a), resid(m_a), xlab = "Nilai prediksi", ylab = "Residual",
main = "Residual vs prediksi"); abline(h = 0, lty = 2)

par(mfrow = c(1, 1))
# 7. SIMPAN OUTPUT & SESSION INFO
write.csv(desk, "Ringkasan_Deskriptif_TB.csv", row.names = FALSE)
write.csv(dat_long, "data_tb_long.csv", row.names = FALSE)
ggsave("Profil_TB.png", p_profil, width = 7, height = 4.5, dpi = 300)
ggsave("Spaghetti_TB.png", p_spag, width = 9, height = 4.5, dpi = 300)
message("Selesai. Output disimpan di: ", getwd())
## Selesai. Output disimpan di: /Users/cang/Downloads/untitled folder
print(sessionInfo())
## R version 4.6.1 (2026-06-24)
## Platform: aarch64-apple-darwin23
## Running under: macOS Ventura 13.3.1
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.6/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## time zone: Asia/Makassar
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] lmerTest_3.2-1 effectsize_1.0.3 car_3.1-5 carData_3.0-6
## [5] rstatix_1.1.0 emmeans_2.0.4 afex_1.5-1 lme4_2.0-6
## [9] Matrix_1.7-5 ggplot2_4.0.3 tidyr_1.3.2 dplyr_1.2.1
##
## loaded via a namespace (and not attached):
## [1] tidyselect_1.2.1 farver_2.1.2 S7_0.2.2
## [4] fastmap_1.2.0 reshape_0.8.10 bayestestR_0.19.0
## [7] digest_0.6.39 rpart_4.1.27 estimability_2.0.0
## [10] lifecycle_1.0.5 cluster_2.1.8.2 magrittr_2.0.5
## [13] compiler_4.6.1 rlang_1.3.0 Hmisc_5.3-0
## [16] sass_0.4.10 tools_4.6.1 utf8_1.2.6
## [19] yaml_2.3.12 data.table_1.18.6.1 ggsignif_0.6.4
## [22] knitr_1.51 labeling_0.4.3 htmlwidgets_1.6.4
## [25] plyr_1.8.9 RColorBrewer_1.1-3 abind_1.4-8
## [28] withr_3.0.3 foreign_0.8-91 purrr_1.2.2
## [31] numDeriv_2016.8-1.1 nnet_7.3-20 grid_4.6.1
## [34] datawizard_1.4.0 ggpubr_1.0.0 colorspace_2.1-3
## [37] scales_1.4.0 MASS_7.3-65 insight_1.5.4
## [40] cli_3.6.6 mvtnorm_1.4-2 rmarkdown_2.31
## [43] reformulas_0.4.4 generics_0.1.4 performance_0.18.2
## [46] rstudioapi_0.19.0 reshape2_1.4.5 parameters_0.29.3
## [49] readxl_1.5.0 minqa_1.2.8 cachem_1.1.0
## [52] stringr_1.6.0 splines_4.6.1 parallel_4.6.1
## [55] WRS2_1.1-7 cellranger_1.1.0 base64enc_0.1-6
## [58] vctrs_0.7.3 boot_1.3-32 jsonlite_2.0.0
## [61] pbkrtest_0.5.5 Formula_1.2-6 htmlTable_2.5.0
## [64] jquerylib_0.1.4 glue_1.8.1 nloptr_2.2.1
## [67] stringi_1.8.9 gtable_0.3.6 tibble_3.3.1
## [70] pillar_1.11.1 htmltools_0.5.9 R6_2.6.1
## [73] Rdpack_2.6.6 evaluate_1.0.5 lattice_0.22-9
## [76] rbibutils_2.4.1 backports_1.5.1 broom_1.0.13
## [79] bslib_0.12.0 Rcpp_1.1.2 gridExtra_2.3.1
## [82] nlme_3.1-169 checkmate_2.3.4 xfun_0.60
## [85] pkgconfig_2.0.3