Performs Fisher's exact test for testing the null of independence of rows and columns in a contingency table.
Wrappers around the R base function fisher.test()
but
have the advantage of performing pairwise and row-wise fisher tests, the
post-hoc tests following a significant chi-square test of homogeneity for 2xc
and rx2 contingency tables.
fisher_test(
xtab,
workspace = 2e+05,
alternative = "two.sided",
conf.int = TRUE,
conf.level = 0.95,
simulate.p.value = FALSE,
B = 2000,
detailed = FALSE,
...
)
pairwise_fisher_test(xtab, p.adjust.method = "holm", detailed = FALSE, ...)
row_wise_fisher_test(xtab, p.adjust.method = "holm", detailed = FALSE, ...)
a contingency table in a matrix form.
an integer specifying the size of the workspace
used in the network algorithm. In units of 4 bytes. Only used for
non-simulated p-values larger than \(2 \times 2\) tables.
Since R version 3.5.0, this also increases the internal stack size
which allows larger problems to be solved, however sometimes needing
hours. In such cases, simulate.p.values=TRUE
may be more
reasonable.
indicates the alternative hypothesis and must be
one of "two.sided"
, "greater"
or "less"
.
You can specify just the initial letter. Only used in the
\(2 \times 2\) case.
logical indicating if a confidence interval for the odds ratio in a \(2 \times 2\) table should be computed (and returned).
confidence level for the returned confidence
interval. Only used in the \(2 \times 2\) case and if
conf.int = TRUE
.
a logical indicating whether to compute p-values by Monte Carlo simulation, in larger than \(2 \times 2\) tables.
an integer specifying the number of replicates used in the Monte Carlo test.
logical value. Default is FALSE. If TRUE, a detailed result is shown.
Other arguments passed to the function fisher_test()
.
method to adjust p values for multiple comparisons. Used when pairwise comparisons are performed. Allowed values include "holm", "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr", "none". If you don't want to adjust the p value (not recommended), use p.adjust.method = "none".
return a data frame with some the following columns:
group
: the categories in the row-wise proportion tests.
p
: p-value.
p.adj
: the adjusted p-value.
method
: the used statistical test.
p.signif,
p.adj.signif
: the significance level of p-values and adjusted p-values,
respectively.
estimate
: an estimate of the odds ratio. Only
present in the 2 by 2 case.
alternative
: a character string
describing the alternative hypothesis.
conf.low,conf.high
: a
confidence interval for the odds ratio. Only present in the 2 by 2 case and
if argument conf.int = TRUE.
The returned object has an attribute called args, which is a list holding the test arguments.
fisher_test()
: performs Fisher's exact test for testing the null of
independence of rows and columns in a contingency table with fixed
marginals. Wrapper around the function fisher.test()
.
pairwise_fisher_test()
: pairwise comparisons between proportions, a post-hoc
tests following a significant Fisher's exact test of homogeneity for 2xc
design.
row_wise_fisher_test()
: performs row-wise Fisher's exact test of count data, a post-hoc tests following a significant chi-square test
of homogeneity for rx2 contingency table. The test is conducted for each category (row).
# Comparing two proportions
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Data: frequencies of smokers between two groups
xtab <- as.table(rbind(c(490, 10), c(400, 100)))
dimnames(xtab) <- list(
group = c("grp1", "grp2"),
smoker = c("yes", "no")
)
xtab
#> smoker
#> group yes no
#> grp1 490 10
#> grp2 400 100
# compare the proportion of smokers
fisher_test(xtab, detailed = TRUE)
#> # A tibble: 1 × 8
#> n estimate p conf.low conf.high method alter…¹ p.sig…²
#> * <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
#> 1 1000 12.2 8.77e-22 6.27 26.6 Fisher's Exact test two.si… ****
#> # … with abbreviated variable names ¹alternative, ²p.signif
# Homogeneity of proportions between groups
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# H0: the proportion of smokers is similar in the four groups
# Ha: this proportion is different in at least one of the populations.
#
# Data preparation
grp.size <- c( 106, 113, 156, 102 )
smokers <- c( 50, 100, 139, 80 )
no.smokers <- grp.size - smokers
xtab <- as.table(rbind(
smokers,
no.smokers
))
dimnames(xtab) <- list(
Smokers = c("Yes", "No"),
Groups = c("grp1", "grp2", "grp3", "grp4")
)
xtab
#> Groups
#> Smokers grp1 grp2 grp3 grp4
#> Yes 50 100 139 80
#> No 56 13 17 22
# Compare the proportions of smokers between groups
fisher_test(xtab, detailed = TRUE)
#> # A tibble: 1 × 5
#> n p method alternative p.signif
#> * <dbl> <dbl> <chr> <chr> <chr>
#> 1 477 6.1e-15 Fisher's Exact test two.sided ****
# Pairwise comparison between groups
pairwise_fisher_test(xtab)
#> # A tibble: 6 × 6
#> group1 group2 n p p.adj p.adj.signif
#> * <chr> <chr> <dbl> <dbl> <dbl> <chr>
#> 1 grp1 grp2 219 2.39e-11 1.2 e-10 ****
#> 2 grp1 grp3 262 1.22e-13 7.32e-13 ****
#> 3 grp1 grp4 208 3.79e- 6 1.52e- 5 ****
#> 4 grp2 grp3 269 1 e+ 0 1 e+ 0 ns
#> 5 grp2 grp4 215 6.35e- 2 1.27e- 1 ns
#> 6 grp3 grp4 258 2.17e- 2 6.51e- 2 ns
# Pairwise proportion tests
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Data: Titanic
xtab <- as.table(rbind(
c(122, 167, 528, 673),
c(203, 118, 178, 212)
))
dimnames(xtab) <- list(
Survived = c("No", "Yes"),
Class = c("1st", "2nd", "3rd", "Crew")
)
xtab
#> Class
#> Survived 1st 2nd 3rd Crew
#> No 122 167 528 673
#> Yes 203 118 178 212
# Compare the proportion of survived between groups
pairwise_fisher_test(xtab)
#> # A tibble: 6 × 6
#> group1 group2 n p p.adj p.adj.signif
#> * <chr> <chr> <dbl> <dbl> <dbl> <chr>
#> 1 1st 2nd 610 2.78e- 7 8.34e- 7 ****
#> 2 1st 3rd 1031 3.68e-30 1.84e-29 ****
#> 3 1st Crew 1210 1.81e-34 1.09e-33 ****
#> 4 2nd 3rd 991 8.19e- 7 1.64e- 6 ****
#> 5 2nd Crew 1170 2.77e- 8 1.11e- 7 ****
#> 6 3rd Crew 1591 5.98e- 1 5.98e- 1 ns
# Row-wise proportion tests
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Data: Titanic
xtab <- as.table(rbind(
c(180, 145), c(179, 106),
c(510, 196), c(862, 23)
))
dimnames(xtab) <- list(
Class = c("1st", "2nd", "3rd", "Crew"),
Gender = c("Male", "Female")
)
xtab
#> Gender
#> Class Male Female
#> 1st 180 145
#> 2nd 179 106
#> 3rd 510 196
#> Crew 862 23
# Compare the proportion of males and females in each category
row_wise_fisher_test(xtab)
#> # A tibble: 4 × 5
#> group n p p.adj p.adj.signif
#> * <chr> <dbl> <dbl> <dbl> <chr>
#> 1 1st 2201 9.38e-25 2.81e-24 ****
#> 2 2nd 2201 3.96e-11 7.92e-11 ****
#> 3 3rd 2201 8.67e- 7 8.67e- 7 ****
#> 4 Crew 2201 8.02e-85 3.21e-84 ****
# A r x c table Agresti (2002, p. 57) Job Satisfaction
Job <- matrix(c(1,2,1,0, 3,3,6,1, 10,10,14,9, 6,7,12,11), 4, 4,
dimnames = list(income = c("< 15k", "15-25k", "25-40k", "> 40k"),
satisfaction = c("VeryD", "LittleD", "ModerateS", "VeryS")))
fisher_test(Job)
#> # A tibble: 1 × 3
#> n p p.signif
#> * <dbl> <dbl> <chr>
#> 1 96 0.783 ns
fisher_test(Job, simulate.p.value = TRUE, B = 1e5)
#> # A tibble: 1 × 3
#> n p p.signif
#> * <dbl> <dbl> <chr>
#> 1 96 0.783 ns