blob: ea7a6a24a53800b440c55c4226a320daf042f8fe [file] [log] [blame]
# File src/library/stats/R/pairwise.R
# Part of the R package, https://www.R-project.org
#
# Copyright (C) 1995-2015 The R Core Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of the GNU General Public License is available at
# https://www.R-project.org/Licenses/
pairwise.t.test <-
function(x, g, p.adjust.method = p.adjust.methods, pool.sd = !paired,
paired = FALSE, alternative = c("two.sided", "less", "greater"), ...)
{
if (paired & pool.sd)
stop("pooling of SD is incompatible with paired tests")
DNAME <- paste(deparse(substitute(x)), "and", deparse(substitute(g)))
g <- factor(g)
p.adjust.method <- match.arg(p.adjust.method)
alternative <- match.arg(alternative)
if (pool.sd)
{
METHOD <- "t tests with pooled SD"
xbar <- tapply(x, g, mean, na.rm = TRUE)
s <- tapply(x, g, sd, na.rm = TRUE)
n <- tapply(!is.na(x), g, sum)
degf <- n - 1
total.degf <- sum(degf)
pooled.sd <- sqrt(sum(s^2 * degf)/total.degf)
compare.levels <- function(i, j) {
dif <- xbar[i] - xbar[j]
se.dif <- pooled.sd * sqrt(1/n[i] + 1/n[j])
t.val <- dif/se.dif
if (alternative == "two.sided")
2 * pt(-abs(t.val), total.degf)
else
pt(t.val, total.degf,
lower.tail=(alternative == "less"))
}
} else {
METHOD <- if (paired) "paired t tests"
else "t tests with non-pooled SD"
compare.levels <- function(i, j) {
xi <- x[as.integer(g) == i]
xj <- x[as.integer(g) == j]
t.test(xi, xj, paired=paired,
alternative=alternative, ...)$p.value
}
}
PVAL <- pairwise.table(compare.levels, levels(g), p.adjust.method)
ans <- list(method = METHOD, data.name = DNAME,
p.value = PVAL, p.adjust.method=p.adjust.method)
class(ans) <- "pairwise.htest"
ans
}
pairwise.wilcox.test <-
function(x, g, p.adjust.method = p.adjust.methods, paired=FALSE, ...)
{
p.adjust.method <- match.arg(p.adjust.method)
DNAME <- paste(deparse(substitute(x)), "and", deparse(substitute(g)))
g <- factor(g)
METHOD <- if (paired) "Wilcoxon signed rank test"
else "Wilcoxon rank sum test"
compare.levels <- function(i, j) {
xi <- x[as.integer(g) == i]
xj <- x[as.integer(g) == j]
wilcox.test(xi, xj, paired=paired, ...)$p.value
}
PVAL <- pairwise.table(compare.levels, levels(g), p.adjust.method)
ans <- list(method = METHOD, data.name = DNAME,
p.value = PVAL, p.adjust.method=p.adjust.method)
class(ans) <- "pairwise.htest"
ans
}
pairwise.prop.test <-
function (x, n, p.adjust.method = p.adjust.methods, ...)
{
p.adjust.method <- match.arg(p.adjust.method)
METHOD <- "Pairwise comparison of proportions"
DNAME <- deparse(substitute(x))
if (is.matrix(x)) {
if (ncol(x) != 2)
stop("'x' must have 2 columns")
n <- rowSums(x)
x <- x[, 1]
}
else {
DNAME <- paste(DNAME, "out of", deparse(substitute(n)))
if (length(x) != length(n))
stop("'x' and 'n' must have the same length")
}
OK <- complete.cases(x, n)
x <- x[OK]
n <- n[OK]
if (length(x) < 2L)
stop("too few groups")
compare.levels <- function(i, j) {
prop.test(x[c(i,j)], n[c(i,j)], ...)$p.value
}
level.names <- names(x)
if (is.null(level.names)) level.names <- seq_along(x)
PVAL <- pairwise.table(compare.levels, level.names, p.adjust.method)
ans <- list(method = METHOD, data.name = DNAME,
p.value = PVAL, p.adjust.method=p.adjust.method)
class(ans) <- "pairwise.htest"
ans
}
pairwise.table <-
function(compare.levels, level.names, p.adjust.method)
{
ix <- setNames(seq_along(level.names), level.names)
pp <- outer(ix[-1L], ix[-length(ix)],function(ivec, jvec)
sapply(seq_along(ivec), function(k) {
i <- ivec[k]
j <- jvec[k]
if (i > j) compare.levels(i, j) else NA
}))
pp[lower.tri(pp, TRUE)] <- p.adjust(pp[lower.tri(pp, TRUE)],
p.adjust.method)
pp
}
print.pairwise.htest <-
function(x, digits = max(1L, getOption("digits") - 5L), ...)
{
cat("\n\tPairwise comparisons using", x$method, "\n\n")
cat("data: ", x$data.name, "\n\n")
pp <- format.pval(x$p.value, digits=digits, na.form="-")
attributes(pp) <- attributes(x$p.value)
print(pp, quote=FALSE, ...)
cat("\nP value adjustment method:", x$p.adjust.method, "\n")
invisible(x)
}