This repository has been archived by the owner on Mar 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
games_howell.R
143 lines (121 loc) Β· 3.93 KB
/
games_howell.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#' @title Games-Howell post-hoc test
#' @name games_howell
#' @description This function produces results from Games-Howell post-hoc tests
#' for Welch's one-way analysis of variance (ANOVA) (`stats::oneway.test()`).
#'
#' @inheritParams pairwise_comparisons
#'
#' @importFrom stats ptukey qtukey
#' @importFrom utils combn
#' @importFrom dplyr select everything
#'
#' @note This is based on the implementation of Games-Howell test by Aaron
#' Schlegel (https://rpubs.com/aaronsc32) and published on RPubs
#' (https://rpubs.com/aaronsc32/games-howell-test).
#'
#' @keywords internal
# function body
games_howell <- function(data, x, y) {
# ============================ data preparation ==========================
# creating a dataframe
data <-
dplyr::select(
.data = data,
x = !!rlang::enquo(x),
y = !!rlang::enquo(y)
) %>%
tidyr::drop_na(.) %>%
dplyr::mutate(.data = ., x = droplevels(as.factor(x))) %>%
as_tibble(.)
# variables of interest for running the test
grp <- data$x
obs <- data$y
# create combinations
combs <- utils::combn(x = unique(grp), m = 2)
# Statistics that will be used throughout the calculations:
# n = sample size of each group
# groups = number of groups in data
# Mean = means of each group sample
# std = variance of each group sample
n <- tapply(X = obs, INDEX = grp, FUN = length)
groups <- length(tapply(X = obs, INDEX = grp, FUN = length))
Mean <- tapply(X = obs, INDEX = grp, FUN = mean)
std <- tapply(X = obs, INDEX = grp, FUN = var)
# ============================ analysis ===============================
statistics <- lapply(X = 1:NCOL(combs), FUN = function(x) {
# mean difference
mean.diff <- Mean[combs[2, x]] - Mean[combs[1, x]]
# t-values
t <-
(abs(Mean[combs[1, x]] - Mean[combs[2, x]])) /
(sqrt((std[combs[1, x]] / n[combs[1, x]]) +
(std[combs[2, x]] / n[combs[2, x]])))
# degrees of freedom (df)
df <-
((std[combs[1, x]] / n[combs[1, x]] +
std[combs[2, x]] / n[combs[2, x]])^2) /
((((std[combs[1, x]] / n[combs[1, x]])^2 / (n[combs[1, x]] - 1)) +
((std[combs[2, x]] / n[combs[2, x]])^2 / (n[combs[2, x]] - 1))))
# p-values
p <-
stats::ptukey(
q = t * sqrt(2),
nmeans = groups,
df = df,
lower.tail = FALSE
)
# sigma standard error
se <- sqrt(x = 0.5 * (std[combs[1, x]] / n[combs[1, x]] + std[combs[2, x]] / n[combs[2, x]]))
# upper confidence limit for mean difference
conf.high <-
lapply(
X = 1:NCOL(combs),
FUN = function(x) mean.diff + stats::qtukey(p = 0.95, nmeans = groups, df = df) * se
)
# lower confidence limit for mean difference
conf.low <-
lapply(
X = 1:NCOL(combs),
FUN = function(x) mean.diff - stats::qtukey(p = 0.95, nmeans = groups, df = df) * se
)
# Group Combinations
group1 <- as.character(combs[1, x])
group2 <- as.character(combs[2, x])
# Collect all statistics into list
stats <- list(group1, group2, mean.diff, se, t, df, p, conf.high[[1]], conf.low[[1]])
})
# unlist statistics collected earlier
stats.unlisted <- lapply(statistics, function(x) unlist(x))
# create dataframe from flattened list
results <-
data.frame(matrix(
unlist(stats.unlisted),
nrow = length(stats.unlisted),
byrow = TRUE
))
# select columns that should be numeric and change with as.numeric
results[, 3:ncol(results)] <- round(as.numeric(as.matrix(results[, 3:ncol(results)])), digits = 3)
# Rename data frame columns
colnames(results) <-
c(
"group1",
"group2",
"mean.difference",
"se",
"t.value",
"df",
"p.value",
"conf.high",
"conf.low"
)
# converting it to tibble
results %>%
as_tibble(.) %>%
dplyr::select(
.data = .,
group1:mean.difference,
conf.low,
conf.high,
dplyr::everything()
)
}