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