paket <- c(
"tidyverse", "afex", "emmeans", "rstatix",
"car", "effectsize", "lme4", "lmerTest",
"performance", "ggpubr", "pbkrtest"
)
belum_terpasang <- setdiff(
paket,
rownames(installed.packages())
)
if (length(belum_terpasang) > 0) {
install.packages(
belum_terpasang,
repos = "https://cloud.r-project.org"
)
}
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.1 ✔ readr 2.2.0
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.3 ✔ tibble 3.3.1
## ✔ lubridate 1.9.5 ✔ tidyr 1.3.2
## ✔ purrr 1.2.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(afex)
## Loading required package: lme4
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
##
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
##
## Registered S3 method overwritten by 'car':
## method from
## na.action.merMod lme4
## ************
## Welcome to afex. For support visit: http://afex.singmann.science/
## - Functions for ANOVAs: aov_car(), aov_ez(), and aov_4()
## - Methods for calculating p-values with mixed(): 'S', 'KR', 'LRT', and 'PB'
## - 'afex_aov' and 'mixed' objects can be passed to emmeans() for follow-up tests
## - Get and set global package options with: afex_options()
## - Set sum-to-zero contrasts globally: set_sum_contrasts()
## - For example analyses see: browseVignettes("afex")
## ************
##
## Attaching package: 'afex'
##
## The following object is masked from 'package:lme4':
##
## lmer
library(emmeans)
## Welcome to emmeans.
## Caution: You lose important information if you filter this package's results.
## See '? untidy'
library(rstatix)
##
## Attaching package: 'rstatix'
##
## The following object is masked from 'package:stats':
##
## filter
library(car)
## Loading required package: carData
##
## Attaching package: 'car'
##
## The following object is masked from 'package:dplyr':
##
## recode
##
## The following object is masked from 'package:purrr':
##
## some
library(effectsize)
##
## Attaching package: 'effectsize'
##
## The following objects are masked from 'package:rstatix':
##
## cohens_d, eta_squared, omega_squared
library(lme4)
library(lmerTest)
##
## Attaching package: 'lmerTest'
##
## The following object is masked from 'package:lme4':
##
## lmer
##
## The following object is masked from 'package:stats':
##
## step
library(performance)
library(ggpubr)
options(
contrasts = c("contr.sum", "contr.poly")
)
afex_options(
emmeans_model = "multivariate"
)
theme_set(
theme_bw(base_size = 12)
)
dat_wide <- read.csv(
"data_tds_hipertensi_wide_dummy.csv",
stringsAsFactors = FALSE
)
head(dat_wide)
## id kelompok usia jk TDS_M0 TDS_M4 TDS_M8 TDS_M12
## 1 P001 Kontrol 47 L 148.9 147.7 146.2 138.9
## 2 P002 Kontrol 43 L 155.0 149.4 157.9 152.6
## 3 P003 Kontrol 64 P 153.2 152.1 151.4 145.9
## 4 P004 Kontrol 61 P 146.4 141.8 144.8 132.5
## 5 P005 Kontrol 64 P 133.4 146.3 143.6 141.7
## 6 P006 Kontrol 53 P 158.2 161.5 140.5 147.8
str(dat_wide)
## 'data.frame': 90 obs. of 8 variables:
## $ id : chr "P001" "P002" "P003" "P004" ...
## $ kelompok: chr "Kontrol" "Kontrol" "Kontrol" "Kontrol" ...
## $ usia : int 47 43 64 61 64 53 60 64 46 65 ...
## $ jk : chr "L" "L" "P" "P" ...
## $ TDS_M0 : num 149 155 153 146 133 ...
## $ TDS_M4 : num 148 149 152 142 146 ...
## $ TDS_M8 : num 146 158 151 145 144 ...
## $ TDS_M12 : num 139 153 146 132 142 ...
names(dat_wide)
## [1] "id" "kelompok" "usia" "jk" "TDS_M0" "TDS_M4" "TDS_M8"
## [8] "TDS_M12"
dim(dat_wide)
## [1] 90 8
table(dat_wide$kelompok)
##
## DASH DASH+AF Kontrol
## 30 30 30
colSums(is.na(dat_wide))
## id kelompok usia jk TDS_M0 TDS_M4 TDS_M8 TDS_M12
## 0 0 0 0 0 0 0 0
anyDuplicated(dat_wide$id)
## [1] 0
kel_lab <- c("Kontrol", "DASH", "DASH+AF")
minggu <- c(0, 4, 8, 12)
dat_wide <- dat_wide %>%
mutate(
id = factor(id),
kelompok = factor(
kelompok,
levels = kel_lab
),
jk = factor(
jk,
levels = c("L", "P")
)
)
dat_long <- dat_wide %>%
pivot_longer(
cols = c(
TDS_M0, TDS_M4,
TDS_M8, TDS_M12
),
names_to = "waktu",
values_to = "tds"
) %>%
mutate(
waktu = factor(
waktu,
levels = c(
"TDS_M0", "TDS_M4",
"TDS_M8", "TDS_M12"
),
labels = c("M0", "M4", "M8", "M12")
),
minggu = as.numeric(
sub("M", "", as.character(waktu))
)
)
head(dat_long)
## # A tibble: 6 × 7
## id kelompok usia jk waktu tds minggu
## <fct> <fct> <int> <fct> <fct> <dbl> <dbl>
## 1 P001 Kontrol 47 L M0 149. 0
## 2 P001 Kontrol 47 L M4 148. 4
## 3 P001 Kontrol 47 L M8 146. 8
## 4 P001 Kontrol 47 L M12 139. 12
## 5 P002 Kontrol 43 L M0 155 0
## 6 P002 Kontrol 43 L M4 149. 4
nrow(dat_long)
## [1] 360
table(
dat_long$kelompok,
dat_long$waktu
)
##
## M0 M4 M8 M12
## Kontrol 30 30 30 30
## DASH 30 30 30 30
## DASH+AF 30 30 30 30
sum(is.na(dat_long$tds))
## [1] 0
deskriptif <- dat_long %>%
group_by(kelompok, waktu) %>%
summarise(
n = n(),
rerata = mean(tds),
sd = sd(tds),
minimum = min(tds),
maksimum = max(tds),
.groups = "drop"
)
print(deskriptif, n = 12)
## # A tibble: 12 × 7
## kelompok waktu n rerata sd minimum maksimum
## <fct> <fct> <int> <dbl> <dbl> <dbl> <dbl>
## 1 Kontrol M0 30 151. 9.71 133. 173.
## 2 Kontrol M4 30 149. 11.7 128 169.
## 3 Kontrol M8 30 148. 9.79 133 176.
## 4 Kontrol M12 30 146. 10.7 126. 164.
## 5 DASH M0 30 151. 9.54 135. 173.
## 6 DASH M4 30 147. 10.7 129. 166.
## 7 DASH M8 30 144. 12.6 122. 170.
## 8 DASH M12 30 141. 12.1 124. 170.
## 9 DASH+AF M0 30 151. 10.4 129. 171.
## 10 DASH+AF M4 30 144. 13.2 116. 170.
## 11 DASH+AF M8 30 141. 10.5 118. 160.
## 12 DASH+AF M12 30 136. 11.7 105. 158.
print(deskriptif, n = 12)
## # A tibble: 12 × 7
## kelompok waktu n rerata sd minimum maksimum
## <fct> <fct> <int> <dbl> <dbl> <dbl> <dbl>
## 1 Kontrol M0 30 151. 9.71 133. 173.
## 2 Kontrol M4 30 149. 11.7 128 169.
## 3 Kontrol M8 30 148. 9.79 133 176.
## 4 Kontrol M12 30 146. 10.7 126. 164.
## 5 DASH M0 30 151. 9.54 135. 173.
## 6 DASH M4 30 147. 10.7 129. 166.
## 7 DASH M8 30 144. 12.6 122. 170.
## 8 DASH M12 30 141. 12.1 124. 170.
## 9 DASH+AF M0 30 151. 10.4 129. 171.
## 10 DASH+AF M4 30 144. 13.2 116. 170.
## 11 DASH+AF M8 30 141. 10.5 118. 160.
## 12 DASH+AF M12 30 136. 11.7 105. 158.
# Hitung interval kepercayaan 95%
deskriptif <- deskriptif %>%
mutate(
minggu = as.numeric(
sub("M", "", as.character(waktu))
),
se = sd / sqrt(n),
batas_bawah = rerata - qt(0.975, df = n - 1) * se,
batas_atas = rerata + qt(0.975, df = n - 1) * se
)
# Buat grafik
grafik_tds <- ggplot(
deskriptif,
aes(
x = minggu,
y = rerata,
colour = kelompok,
group = kelompok
)
) +
geom_line(linewidth = 1) +
geom_point(size = 3) +
geom_errorbar(
aes(
ymin = batas_bawah,
ymax = batas_atas
),
width = 0.5
) +
scale_x_continuous(
breaks = c(0, 4, 8, 12)
) +
scale_colour_manual(
values = c(
"Kontrol" = "#64748B",
"DASH" = "#2563EB",
"DASH+AF" = "#0B6B4F"
)
) +
labs(
title = "Perubahan Rerata Tekanan Darah Sistolik",
subtitle = "Data dummy; garis vertikal = interval kepercayaan 95%",
x = "Minggu ke-",
y = "Rerata TDS (mmHg)",
colour = "Kelompok"
) +
theme_bw(base_size = 12) +
theme(
legend.position = "bottom"
)
print(grafik_tds)

hasil_outlier <- dat_long %>%
group_by(kelompok, waktu) %>%
rstatix::identify_outliers(tds) %>%
ungroup()
print(hasil_outlier, n = Inf)
## # A tibble: 1 × 9
## kelompok waktu id usia jk tds minggu is.outlier is.extreme
## <fct> <fct> <fct> <int> <fct> <dbl> <dbl> <lgl> <lgl>
## 1 DASH+AF M12 P090 42 P 105. 12 TRUE FALSE
hasil_normalitas <- dat_long %>%
group_by(kelompok, waktu) %>%
rstatix::shapiro_test(tds) %>%
ungroup()
print(hasil_normalitas, n = 12)
## # A tibble: 12 × 5
## kelompok waktu variable statistic p
## <fct> <fct> <chr> <dbl> <dbl>
## 1 Kontrol M0 tds 0.980 0.822
## 2 Kontrol M4 tds 0.969 0.521
## 3 Kontrol M8 tds 0.964 0.385
## 4 Kontrol M12 tds 0.969 0.510
## 5 DASH M0 tds 0.976 0.713
## 6 DASH M4 tds 0.963 0.367
## 7 DASH M8 tds 0.966 0.429
## 8 DASH M12 tds 0.945 0.122
## 9 DASH+AF M0 tds 0.984 0.918
## 10 DASH+AF M4 tds 0.987 0.963
## 11 DASH+AF M8 tds 0.984 0.918
## 12 DASH+AF M12 tds 0.949 0.156
grafik_qq <- ggplot(
dat_long,
aes(sample = tds)
) +
stat_qq(size = 1.5, alpha = 0.7) +
stat_qq_line(colour = "#0B6B4F") +
facet_grid(waktu ~ kelompok) +
labs(
title = "Pemeriksaan Normalitas TDS",
x = "Kuantil teoretis",
y = "Kuantil data"
) +
theme_bw(base_size = 11)
print(grafik_qq)

d1 <- dat_long %>%
filter(kelompok == "DASH+AF") %>%
droplevels()
table(d1$waktu)
##
## M0 M4 M8 M12
## 30 30 30 30
anova_satu <- rstatix::anova_test(
data = d1,
dv = tds,
wid = id,
within = waktu,
effect.size = "pes"
)
print(anova_satu)
## ANOVA Table (type III tests)
##
## $ANOVA
## Effect DFn DFd F p p<.05 pes
## 1 waktu 3 87 51.037 4e-19 * 0.638
##
## $`Mauchly's Test for Sphericity`
## Effect W p p<.05
## 1 waktu 0.812 0.33
##
## $`Sphericity Corrections`
## Effect GGe DF[GG] p[GG] p[GG]<.05 HFe DF[HF] p[HF]
## 1 waktu 0.868 2.6, 75.53 6.6e-17 * 0.961 2.88, 83.64 1.78e-18
## p[HF]<.05
## 1 *
aov1 <- afex::aov_ez(
id = "id",
dv = "tds",
data = d1,
within = "waktu",
anova_table = list(
es = c("ges", "pes"),
correction = "none"
)
)
# Rerata estimasi pada setiap waktu
em1 <- emmeans::emmeans(
aov1,
~ waktu
)
print(em1)
## waktu emmean SE df lower.CL upper.CL
## M0 151 1.89 29 147 155
## M4 144 2.41 29 139 149
## M8 141 1.92 29 137 144
## M12 136 2.13 29 132 141
##
## Confidence level used: 0.95
# Bandingkan seluruh pasangan waktu
posthoc_waktu <- pairs(
em1,
adjust = "bonferroni"
)
print(posthoc_waktu)
## contrast estimate SE df t.ratio p.value
## M0 - M4 6.57 1.08 29 6.080 <0.0001
## M0 - M8 10.36 1.13 29 9.136 <0.0001
## M0 - M12 14.61 1.36 29 10.709 <0.0001
## M4 - M8 3.79 1.21 29 3.128 0.0239
## M4 - M12 8.04 1.44 29 5.593 <0.0001
## M8 - M12 4.26 1.09 29 3.907 0.0031
##
## P value adjustment: bonferroni method for 6 tests
hasil_levene <- dat_long %>%
group_by(waktu) %>%
rstatix::levene_test(tds ~ kelompok) %>%
ungroup()
print(hasil_levene)
## # A tibble: 4 × 5
## waktu df1 df2 statistic p
## <fct> <int> <int> <dbl> <dbl>
## 1 M0 2 87 0.175 0.840
## 2 M4 2 87 0.283 0.754
## 3 M8 2 87 1.71 0.186
## 4 M12 2 87 0.482 0.619
hasil_boxm <- rstatix::box_m(
dat_wide[, c(
"TDS_M0", "TDS_M4",
"TDS_M8", "TDS_M12"
)],
dat_wide$kelompok
)
print(hasil_boxm)
## # A tibble: 1 × 4
## statistic p.value parameter method
## <dbl> <dbl> <dbl> <chr>
## 1 20.5 0.430 20 Box's M-test for Homogeneity of Covariance Matric…
anova_campuran <- rstatix::anova_test(
data = dat_long,
dv = tds,
wid = id,
between = kelompok,
within = waktu,
effect.size = "pes"
)
print(anova_campuran)
## ANOVA Table (type II tests)
##
## $ANOVA
## Effect DFn DFd F p p<.05 pes
## 1 kelompok 2 87 2.137 1.24e-01 0.047
## 2 waktu 3 261 69.270 5.54e-33 * 0.443
## 3 kelompok:waktu 6 261 5.570 1.88e-05 * 0.114
##
## $`Mauchly's Test for Sphericity`
## Effect W p p<.05
## 1 waktu 0.877 0.047 *
## 2 kelompok:waktu 0.877 0.047 *
##
## $`Sphericity Corrections`
## Effect GGe DF[GG] p[GG] p[GG]<.05 HFe DF[HF]
## 1 waktu 0.922 2.77, 240.68 1.28e-30 * 0.955 2.87, 249.37
## 2 kelompok:waktu 0.922 5.53, 240.68 3.58e-05 * 0.955 5.73, 249.37
## p[HF] p[HF]<.05
## 1 1.25e-31 *
## 2 2.72e-05 *
tabel_anova_campuran <- rstatix::get_anova_table(
anova_campuran,
correction = "auto"
)
print(tabel_anova_campuran)
## ANOVA Table (type II tests)
##
## Effect DFn DFd F p p<.05 pes
## 1 kelompok 2.00 87.00 2.137 1.24e-01 0.047
## 2 waktu 2.77 240.68 69.270 1.28e-30 * 0.443
## 3 kelompok:waktu 5.53 240.68 5.570 3.58e-05 * 0.114
aov2 <- afex::aov_ez(
id = "id",
dv = "tds",
data = dat_long,
between = "kelompok",
within = "waktu",
type = 3,
anova_table = list(
es = c("ges", "pes"),
correction = "GG"
)
)
print(aov2)
## Anova Table (Type 3 tests)
##
## Response: tds
## Effect df MSE F ges pes p.value
## 1 kelompok 2, 87 423.12 2.14 .040 .047 .124
## 2 waktu 2.77, 240.68 25.64 69.27 *** .103 .443 <.001
## 3 kelompok:waktu 5.53, 240.68 25.64 5.57 *** .018 .114 <.001
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '+' 0.1 ' ' 1
##
## Sphericity correction method: GG
# Rerata estimasi kelompok pada setiap waktu
em_kelompok <- emmeans::emmeans(
aov2,
~ kelompok | waktu
)
# Perbandingan pasangan kelompok
posthoc_kelompok <- pairs(
em_kelompok,
adjust = "tukey"
)
print(posthoc_kelompok)
## waktu = M0:
## contrast estimate SE df t.ratio p.value
## Kontrol - DASH -0.197 2.55 87 -0.077 0.9967
## Kontrol - (DASH+AF) 0.100 2.55 87 0.039 0.9992
## DASH - (DASH+AF) 0.297 2.55 87 0.116 0.9926
##
## waktu = M4:
## contrast estimate SE df t.ratio p.value
## Kontrol - DASH 1.497 3.08 87 0.486 0.8781
## Kontrol - (DASH+AF) 4.580 3.08 87 1.487 0.3020
## DASH - (DASH+AF) 3.083 3.08 87 1.001 0.5781
##
## waktu = M8:
## contrast estimate SE df t.ratio p.value
## Kontrol - DASH 4.370 2.85 87 1.534 0.2803
## Kontrol - (DASH+AF) 7.750 2.85 87 2.720 0.0213
## DASH - (DASH+AF) 3.380 2.85 87 1.186 0.4645
##
## waktu = M12:
## contrast estimate SE df t.ratio p.value
## Kontrol - DASH 5.100 2.97 87 1.717 0.2047
## Kontrol - (DASH+AF) 9.527 2.97 87 3.207 0.0053
## DASH - (DASH+AF) 4.427 2.97 87 1.490 0.3006
##
## P value adjustment: tukey method for comparing a family of 3 estimates
# Perubahan M12 - M0 dalam setiap kelompok
em_waktu_kelompok <- emmeans::emmeans(
aov2,
~ waktu | kelompok
)
perubahan <- emmeans::contrast(
em_waktu_kelompok,
method = list(
"M12 - M0" = c(-1, 0, 0, 1)
)
)
print(perubahan)
## kelompok = Kontrol:
## contrast estimate SE df t.ratio p.value
## M12 - M0 -5.19 1.42 87 -3.641 0.0005
##
## kelompok = DASH:
## contrast estimate SE df t.ratio p.value
## M12 - M0 -10.48 1.42 87 -7.359 <0.0001
##
## kelompok = DASH+AF:
## contrast estimate SE df t.ratio p.value
## M12 - M0 -14.61 1.42 87 -10.259 <0.0001
# Bandingkan perubahan tersebut antarkelompok
beda_perubahan <- pairs(
perubahan,
by = NULL,
adjust = "holm"
)
print(beda_perubahan)
## contrast estimate SE df t.ratio p.value
## (M12 - M0 Kontrol) - (M12 - M0 DASH) 5.30 2.01 87 2.629 0.0202
## (M12 - M0 Kontrol) - (M12 - M0 DASH+AF) 9.43 2.01 87 4.679 <0.0001
## (M12 - M0 DASH) - (M12 - M0 DASH+AF) 4.13 2.01 87 2.050 0.0434
##
## P value adjustment: holm method for 3 tests
perubahan_baseline <- emmeans::contrast(
em_waktu_kelompok,
method = "trt.vs.ctrl",
ref = 1,
adjust = "holm"
)
print(perubahan_baseline)
## kelompok = Kontrol:
## contrast estimate SE df t.ratio p.value
## M4 - M0 -2.09 1.08 87 -1.940 0.0732
## M8 - M0 -2.71 1.27 87 -2.123 0.0732
## M12 - M0 -5.19 1.42 87 -3.641 0.0014
##
## kelompok = DASH:
## contrast estimate SE df t.ratio p.value
## M4 - M0 -3.78 1.08 87 -3.512 0.0007
## M8 - M0 -7.27 1.27 87 -5.705 <0.0001
## M12 - M0 -10.48 1.42 87 -7.359 <0.0001
##
## kelompok = DASH+AF:
## contrast estimate SE df t.ratio p.value
## M4 - M0 -6.57 1.08 87 -6.099 <0.0001
## M8 - M0 -10.36 1.27 87 -8.124 <0.0001
## M12 - M0 -14.61 1.42 87 -10.259 <0.0001
##
## P value adjustment: holm method for 3 tests
# Model 1: intersep acak
lmm1 <- lmerTest::lmer(
tds ~ kelompok * waktu + (1 | id),
data = dat_long,
REML = TRUE
)
# Model 2: intersep dan kemiringan acak
lmm2 <- lmerTest::lmer(
tds ~ kelompok * waktu + (1 + minggu | id),
data = dat_long,
REML = TRUE
)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, : Model failed to converge with max|grad| = 0.0165734 (tol = 0.002, component 1)
## See ?lme4::convergence and ?lme4::troubleshooting.
dat_long <- dat_long %>%
mutate(
minggu_skala = (minggu - 6) / 4
)
lmm2 <- lmerTest::lmer(
tds ~ kelompok * waktu +
(1 + minggu_skala | id),
data = dat_long,
REML = TRUE,
control = lme4::lmerControl(
optimizer = "bobyqa",
optCtrl = list(maxfun = 200000)
)
)
# Pesan pemeriksaan konvergensi
lmm2@optinfo$conv$lme4$messages
## NULL
# Kode optimizer
lmm2@optinfo$conv$opt
## [1] 0
# Pemeriksaan singularitas
lme4::isSingular(lmm2)
## [1] FALSE
hasil_lmm <- anova(
lmm2,
type = 3,
ddf = "Kenward-Roger"
)
print(hasil_lmm)
## Type III Analysis of Variance Table with Kenward-Roger's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## kelompok 82.66 41.33 2 87.00 2.1366 0.1242076
## waktu 2963.30 987.77 3 185.37 50.8295 < 2.2e-16 ***
## kelompok:waktu 489.70 81.62 6 206.40 4.1952 0.0005271 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Simpan pengaturan tampilan
pengaturan_lama <- par(no.readonly = TRUE)
par(mfrow = c(2, 2))
# 1. Normalitas residual
qqnorm(
resid(lmm2),
main = "Q-Q residual"
)
qqline(resid(lmm2), col = "red")
# 2. Residual terhadap nilai prediksi
plot(
fitted(lmm2),
resid(lmm2),
xlab = "TDS prediksi",
ylab = "Residual",
main = "Residual vs prediksi"
)
abline(h = 0, col = "red", lty = 2)
# 3. Normalitas intersep acak
efek_acak <- lme4::ranef(lmm2)$id
qqnorm(
efek_acak[, "(Intercept)"],
main = "Q-Q intersep acak"
)
qqline(
efek_acak[, "(Intercept)"],
col = "red"
)
# 4. Normalitas kemiringan acak
qqnorm(
efek_acak[, "minggu_skala"],
main = "Q-Q kemiringan acak"
)
qqline(
efek_acak[, "minggu_skala"],
col = "red"
)

# Pulihkan pengaturan
par(pengaturan_lama)
perbandingan_model <- anova(
lmm1,
lmm2,
refit = FALSE
)
print(perbandingan_model)
## Data: dat_long
## Models:
## lmm1: tds ~ kelompok * waktu + (1 | id)
## lmm2: tds ~ kelompok * waktu + (1 + minggu_skala | id)
## npar AIC BIC logLik -2*log(L) Chisq Df Pr(>Chisq)
## lmm1 14 2425.2 2479.6 -1198.6 2397.2
## lmm2 16 2419.4 2481.6 -1193.7 2387.4 9.7383 2 0.00768 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
hasil_icc <- performance::icc(lmm1)
print(hasil_icc)
## # Intraclass Correlation Coefficient
##
## Adjusted ICC: 0.809
## Unadjusted ICC: 0.691
efek_waktu_per_kelompok <- emmeans::joint_tests(
aov2,
by = "kelompok"
)
print(efek_waktu_per_kelompok)
## kelompok = Kontrol:
## model term df1 df2 F.ratio p.value
## waktu 3 87 4.421 0.0061
##
## kelompok = DASH:
## model term df1 df2 F.ratio p.value
## waktu 3 87 19.128 <0.0001
##
## kelompok = DASH+AF:
## model term df1 df2 F.ratio p.value
## waktu 3 87 37.185 <0.0001
efek_kelompok_per_waktu <- emmeans::joint_tests(
aov2,
by = "waktu"
)
print(efek_kelompok_per_waktu)
## waktu = M0:
## model term df1 df2 F.ratio p.value
## kelompok 2 87 0.007 0.9930
##
## waktu = M4:
## model term df1 df2 F.ratio p.value
## kelompok 2 87 1.150 0.3214
##
## waktu = M8:
## model term df1 df2 F.ratio p.value
## kelompok 2 87 3.719 0.0282
##
## waktu = M12:
## model term df1 df2 F.ratio p.value
## kelompok 2 87 5.151 0.0077
efek_waktu_holm <- as.data.frame(
efek_waktu_per_kelompok
) %>%
mutate(
p_holm = p.adjust(p.value, method = "holm")
)
efek_kelompok_holm <- as.data.frame(
efek_kelompok_per_waktu
) %>%
mutate(
p_holm = p.adjust(p.value, method = "holm")
)
print(efek_waktu_holm)
## model term kelompok df1 df2 F.ratio p.value p_holm
## 1 waktu Kontrol 3 87 4.421 6.092613e-03 6.092613e-03
## 4 waktu DASH 3 87 19.128 1.294689e-09 2.589378e-09
## 7 waktu DASH+AF 3 87 37.185 1.463446e-15 4.390337e-15
print(efek_kelompok_holm)
## model term waktu df1 df2 F.ratio p.value p_holm
## 1 kelompok M0 2 87 0.007 0.993023152 0.99302315
## 3 kelompok M4 2 87 1.150 0.321388935 0.64277787
## 5 kelompok M8 2 87 3.719 0.028190942 0.08457283
## 7 kelompok M12 2 87 5.151 0.007690895 0.03076358
tren_dash_af <- emmeans::contrast(
em1,
method = "poly"
)
print(tren_dash_af)
## contrast estimate SE df t.ratio p.value
## linear -47.63 4.61 29 -10.339 <0.0001
## quadratic 2.31 1.54 29 1.500 0.1445
## cubic -3.25 3.47 29 -0.937 0.3565
# Uji multivariat untuk perubahan waktu pada DASH+AF
print(aov1$Anova)
##
## Type III Repeated Measures MANOVA Tests: Pillai test statistic
## Df test stat approx F num Df den Df Pr(>F)
## (Intercept) 1 0.99457 5311.3 1 29 < 2.2e-16 ***
## waktu 1 0.81515 39.7 3 27 4.903e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Uji multivariat kelompok, waktu, dan interaksi
print(aov2$Anova)
##
## Type III Repeated Measures MANOVA Tests: Pillai test statistic
## Df test stat approx F num Df den Df Pr(>F)
## (Intercept) 1 0.99521 18080.1 1 87 < 2.2e-16 ***
## kelompok 2 0.04682 2.1 2 87 0.124208
## waktu 1 0.64223 50.9 3 85 < 2.2e-16 ***
## kelompok:waktu 2 0.23328 3.8 6 172 0.001445 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Uji perubahan antarwaktu pada DASH+AF
hasil_friedman <- rstatix::friedman_test(
d1,
tds ~ waktu | id
)
print(hasil_friedman)
## # A tibble: 1 × 6
## .y. n statistic df p method
## * <chr> <int> <dbl> <dbl> <dbl> <chr>
## 1 tds 30 59.4 3 8.03e-13 Friedman test
# Ukuran efek Kendall's W
efek_friedman <- rstatix::friedman_effsize(
d1,
tds ~ waktu | id
)
print(efek_friedman)
## # A tibble: 1 × 5
## .y. n effsize method magnitude
## * <chr> <int> <dbl> <chr> <ord>
## 1 tds 30 0.660 Kendall W large
print(aov1$Anova)
##
## Type III Repeated Measures MANOVA Tests: Pillai test statistic
## Df test stat approx F num Df den Df Pr(>F)
## (Intercept) 1 0.99457 5311.3 1 29 < 2.2e-16 ***
## waktu 1 0.81515 39.7 3 27 4.903e-10 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Pastikan urutan responden konsisten pada setiap waktu
d1_urut <- d1 %>%
arrange(waktu, id)
posthoc_wilcoxon <- d1_urut %>%
rstatix::wilcox_test(
tds ~ waktu,
paired = TRUE,
p.adjust.method = "bonferroni"
)
print(posthoc_wilcoxon, n = 6)
## # 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 tds M0 M4 30 30 440 0.00000168 1.01e-5 ****
## 2 tds M0 M8 30 30 461 0.0000000112 6.71e-8 ****
## 3 tds M0 M12 30 30 465 0.00000000186 1.12e-8 ****
## 4 tds M4 M8 30 30 365 0.00510 3.06e-2 *
## 5 tds M4 M12 30 30 436 0.00000324 1.94e-5 ****
## 6 tds M8 M12 30 30 399 0.000305 1.83e-3 **
print(hasil_friedman)
## # A tibble: 1 × 6
## .y. n statistic df p method
## * <chr> <int> <dbl> <dbl> <dbl> <chr>
## 1 tds 30 59.4 3 8.03e-13 Friedman test
kolom_tds <- c(
"TDS_M0", "TDS_M4",
"TDS_M8", "TDS_M12"
)
# Matriks kovarians
matriks_kovarians <- cov(
dat_wide[, kolom_tds]
)
print(round(matriks_kovarians, 2))
## TDS_M0 TDS_M4 TDS_M8 TDS_M12
## TDS_M0 95.43 100.35 83.50 82.80
## TDS_M4 100.35 142.75 111.59 118.61
## TDS_M8 83.50 111.59 129.22 114.94
## TDS_M12 82.80 118.61 114.94 144.72
# Matriks korelasi
matriks_korelasi <- cor(
dat_wide[, kolom_tds]
)
print(round(matriks_korelasi, 2))
## TDS_M0 TDS_M4 TDS_M8 TDS_M12
## TDS_M0 1.00 0.86 0.75 0.70
## TDS_M4 0.86 1.00 0.82 0.83
## TDS_M8 0.75 0.82 1.00 0.84
## TDS_M12 0.70 0.83 0.84 1.00
pasangan <- combn(kolom_tds, 2)
varians_selisih <- apply(
pasangan,
2,
function(x) {
var(dat_wide[[x[1]]] - dat_wide[[x[2]]])
}
)
names(varians_selisih) <- apply(
pasangan,
2,
paste,
collapse = " - "
)
print(round(varians_selisih, 2))
## TDS_M0 - TDS_M4 TDS_M0 - TDS_M8 TDS_M0 - TDS_M12 TDS_M4 - TDS_M8
## 37.48 57.65 74.56 48.79
## TDS_M4 - TDS_M12 TDS_M8 - TDS_M12
## 50.26 44.07
grafik_individu <- ggplot(
dat_long,
aes(x = minggu, y = tds, group = id)
) +
geom_line(alpha = 0.25, colour = "grey40") +
stat_summary(
aes(group = kelompok),
fun = mean,
geom = "line",
colour = "#0B6B4F",
linewidth = 1.2
) +
facet_wrap(~ kelompok) +
scale_x_continuous(breaks = c(0, 4, 8, 12)) +
labs(
title = "Lintasan TDS Individu dan Rerata Kelompok",
x = "Minggu ke-",
y = "TDS (mmHg)"
) +
theme_bw()
print(grafik_individu)

em_full <- emmeans::emmeans(
aov2,
~ waktu * kelompok
)
tren_interaksi <- as.data.frame(
emmeans::contrast(
em_full,
interaction = c(
waktu = "poly",
kelompok = "pairwise"
),
adjust = "none"
)
)
tren_linear <- tren_interaksi %>%
filter(waktu_poly == "linear") %>%
mutate(
p_holm = p.adjust(p.value, method = "holm")
)
print(tren_linear)
## waktu_poly kelompok_pairwise estimate SE df t.ratio p.value
## 1 linear Kontrol - DASH 18.76333 6.555447 87 2.862251 5.268628e-03
## 2 linear Kontrol - (DASH+AF) 31.45000 6.555447 87 4.797537 6.599342e-06
## 3 linear DASH - (DASH+AF) 12.68667 6.555447 87 1.935286 5.620348e-02
## p_holm
## 1 1.053726e-02
## 2 1.979803e-05
## 3 5.620348e-02
set.seed(1)
dat_miss <- dat_long
baris_hilang <- sample(
which(dat_miss$waktu != "M0"),
size = 30
)
dat_miss$tds[baris_hilang] <- NA
# Jumlah pengukuran tersedia
sum(!is.na(dat_miss$tds))
## [1] 330
# Jumlah responden yang memiliki data tidak lengkap
dplyr::n_distinct(
dat_miss$id[is.na(dat_miss$tds)]
)
## [1] 25
lmm_miss <- lmerTest::lmer(
tds ~ kelompok * waktu +
(1 + minggu_skala | id),
data = dat_miss,
REML = TRUE,
na.action = na.omit,
control = lme4::lmerControl(
optimizer = "bobyqa",
optCtrl = list(maxfun = 200000)
)
)
# Periksa model
lmm_miss@optinfo$conv$lme4$messages
## NULL
lme4::isSingular(lmm_miss)
## [1] FALSE
# Jumlah pengukuran yang digunakan
nobs(lmm_miss)
## [1] 330
# Uji efek pada data tidak lengkap
hasil_lmm_missing <- anova(
lmm_miss,
type = 3,
ddf = "Kenward-Roger"
)
print(hasil_lmm_missing)
## Type III Analysis of Variance Table with Kenward-Roger's method
## Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
## kelompok 73.58 36.79 2 86.989 1.8978 0.1560568
## waktu 3021.58 1007.19 3 168.124 51.7084 < 2.2e-16 ***
## kelompok:waktu 502.35 83.72 6 185.771 4.2934 0.0004445 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
dir.create(
"hasil_analisis",
showWarnings = FALSE
)
# Simpan tabel utama sebagai CSV
tabel_simpan <- list(
deskriptif = deskriptif,
outlier = hasil_outlier,
normalitas = hasil_normalitas,
levene = hasil_levene,
box_m = hasil_boxm,
anova_campuran = tabel_anova_campuran,
posthoc_waktu = as.data.frame(posthoc_waktu),
posthoc_kelompok = as.data.frame(posthoc_kelompok),
beda_perubahan = as.data.frame(beda_perubahan),
perubahan_baseline = as.data.frame(perubahan_baseline),
efek_waktu_holm = efek_waktu_holm,
efek_kelompok_holm = efek_kelompok_holm,
tren_linear = tren_linear,
friedman = hasil_friedman,
efek_friedman = efek_friedman,
posthoc_wilcoxon = posthoc_wilcoxon
)
for (nama in names(tabel_simpan)) {
write.csv(
tabel_simpan[[nama]],
file = file.path(
"hasil_analisis",
paste0(nama, ".csv")
),
row.names = FALSE
)
}
# Simpan output model dan informasi sesi
capture.output(
print(anova_satu),
print(aov2),
print(aov1$Anova),
print(aov2$Anova),
print(tren_dash_af),
print(hasil_lmm),
print(perbandingan_model),
print(hasil_icc),
print(hasil_lmm_missing),
print(matriks_kovarians),
print(matriks_korelasi),
print(varians_selisih),
sessionInfo(),
file = "hasil_analisis/output_model.txt"
)
# Simpan grafik
ggsave(
"hasil_analisis/grafik_rerata_tds.png",
plot = grafik_tds,
width = 9, height = 6, dpi = 300
)
ggsave(
"hasil_analisis/grafik_qq.png",
plot = grafik_qq,
width = 10, height = 10, dpi = 300
)
ggsave(
"hasil_analisis/grafik_individu.png",
plot = grafik_individu,
width = 12, height = 5, dpi = 300
)
# Simpan objek analisis agar bisa dibuka kembali
save.image(
file = "hasil_analisis/analisis_tds.RData"
)
# Lihat lokasi dan daftar hasil
getwd()
## [1] "/Volumes/DATA NAZMY/MKM/Rstudio/Tugas R_anova"
list.files("hasil_analisis")
## [1] "analisis_tds.RData" "anova_campuran.csv" "beda_perubahan.csv"
## [4] "box_m.csv" "deskriptif.csv" "efek_friedman.csv"
## [7] "efek_kelompok_holm.csv" "efek_waktu_holm.csv" "friedman.csv"
## [10] "grafik_individu.png" "grafik_qq.png" "grafik_rerata_tds.png"
## [13] "levene.csv" "normalitas.csv" "outlier.csv"
## [16] "output_model.txt" "perubahan_baseline.csv" "posthoc_kelompok.csv"
## [19] "posthoc_waktu.csv" "posthoc_wilcoxon.csv" "tren_linear.csv"
install.packages(
c("rmarkdown", "knitr"),
repos = "https://cloud.r-project.org"
)
## package 'knitr' successfully unpacked and SHA256 sums checked
##
## The downloaded binary packages are in
## /var/folders/lj/l50w2ndj6wv7tfq7_9th1gg00000gp/T//Rtmp47zmG8/downloaded_packages