
データの準備と要約

Fisherの正確検定、Fisherの正確確率検定、Fisherの直接確率検定、Fisherの直接法などと呼ばれています。ここでは、Fisherの正確確率検定をタイトルとして使用します。
新たなトレーニング方法が開発され、運動障害を持つ患者(軽度群、重度群)に対して実施された。軽度群と比較して、重度群に対する新トレーニング法の効果について検証した。
仮説
注意
2×2の分割表において、「群間に独立性がある」という帰無仮説は、統計的には「オッズ比=1」と同義であるため、Fisherの正確確率検定の仮説を定式化するために、オッズ比を用いて説明します。オッズ比には専用の検定方法があり、特に多変量解析ではロジスティック回帰分析が有効です。ただし、Fisherの正確検定も2×2分割表における独立性の検定として、オッズ比 = 1 を帰無仮説とするため、オッズ比の有意性を評価するための厳密な方法の一つと言えます。
最初に研究目的に応じてオッズ、オッズ比を定義してください
$オッズ=\frac{新トレーニングの効果あり}{新トレーニングの効果なし}$
$オッズ比=\dfrac{重度群のオッズ}{軽度群のオッズ}$
帰無仮説 H0: オッズ比=1(重度群のオッズ = 軽度群のオッズ)
対立仮説1 H1: オッズ比 > 1(重度群のオッズ > 軽度群のオッズ)➡ 上側検定
対立仮説2 H1: オッズ比 < 1(重度群のオッズ < 軽度群のオッズ)➡ 下側検定
対立仮説3 H1: オッズ比 ≠1(重度群のオッズ ≠ 軽度群のオッズ)➡ 両側検定

サンプルから考えると「仮説2」と「仮説3」は不要と思われますが、統計学備忘録として3つの仮説を取り上げます。
サンプル(架空のサンプルです)
障害レベル; severity(severe=重度, mild=軽度)
効果; effect(yes=あり, no=なし)
severity <- c(rep("severe", 12), rep("mild", 6), rep("severe", 3), rep("mild", 8))
severity <- factor(severity, levels=c("severe", "mild"))
levels(severity)
#[1] "severe" "mild"
effect <- c(rep("yes", 18), rep("no", 11))
effect <- factor(effect, levels=c("yes", "no"))
levels(effect)
#[1] "yes" "no"
tab <- xtabs( ~ severity + effect)
print(tab)
> print(tab)
effect
severity yes no
severe 12 3
mild 6 8
factor()
関数は名義変数をカテゴリカル変数(因子型変数)に変換し、データのカテゴリーは「水準」として定義されます。levels()
関数で表示されるカテゴリカル変数の水準のうち、最初に表示されるカテゴリーがデフォルトで基準カテゴリー(参照カテゴリー)となり、統計モデルでの比較の基点として機能します。relevel()
関数や factor()
関数の levels
引数を使用することで、レベルの順序を指定し、基準カテゴリーを変更することが可能です。
重度群のオッズは$\frac{12}{3}=4$、軽度群のオッズは$\frac{6}{8}=0.75$となります。この比率が「1」か「1ではない」かということを調べるために、下記のオッズ比を利用します。
$オッズ比 =\dfrac{重度群のオッズ}{軽度群のオッズ}= 5.33$
5.33なのでオッズ比は1より大きい結果となりました。オッズ比が高くなると重度群の効果割合が軽度群の効果割合より高いことを意味します。
Rで分割表の作成
分割表の操作については、以下の記事を参照ください。
分割表の周辺合計
addmargins(tab)
> addmargins(tab)
effect
severity yes no Sum
severe 12 3 15
mild 6 8 14
Sum 18 11 29
周辺合計を固定した場合に、考えられる全ての分割表を求めます。
# Define a function to generate and display contingency tables
print_tables <- function() {
total_severe <- 15
total_mild <- 14
total_yes <- 18
total_no <- 11
# Calculate the possible range of values for a
# a corresponds to severe & yes
for (a in max(0, total_yes - total_mild):min(total_yes, total_severe)) {
b <- total_severe - a # severe & no
c <- total_yes - a # mild & yes
d <- total_no - b # mild & no
# Check if b, c, and d are all non-negative integers
if (b >= 0 && c >= 0 && d >= 0 && c <= total_mild && d <= total_mild) {
# Print only the contingency table
cat(sprintf("Effect\n"))
cat(sprintf("Severity Yes No\n"))
cat(sprintf("Severe %d %d\n", a, b))
cat(sprintf("Mild %d %d\n\n", c, d))
}
}
}
# Run the function to display all contingency tables
print_tables()
> print_tables()
Effect
Severity Yes No
Severe 4 11
Mild 14 0
Effect
Severity Yes No
Severe 5 10
Mild 13 1
Effect
Severity Yes No
Severe 6 9
Mild 12 2
Effect
Severity Yes No
Severe 7 8
Mild 11 3
Effect
Severity Yes No
Severe 8 7
Mild 10 4
Effect
Severity Yes No
Severe 9 6
Mild 9 5
Effect
Severity Yes No
Severe 10 5
Mild 8 6
Effect
Severity Yes No
Severe 11 4
Mild 7 7
Effect
Severity Yes No
Severe 12 3
Mild 6 8
Effect
Severity Yes No
Severe 13 2
Mild 5 9
Effect
Severity Yes No
Severe 14 1
Mild 4 10
Effect
Severity Yes No
Severe 15 0
Mild 3 11
考えられる分割表は12組あります。これでFisherの正確検定の準備は完了、有意水準5%で検定してみましょう。研究計画(何を立証したいのか)に従い、以下から適切な検定方法を選択します。
Rの関数 fisher.test()とexact2x2()

板垣様より大変貴重なご意見をいただきました。ありがとうございました。ご意見をもとに加筆しております。
fisher.test()(Rの標準関数)
2×2分割表に対して簡単に使用できる関数であり、周辺度数が固定された条件下での超幾何分布に基づいて、正確な累積確率(central P値)からP値を算出します。Mid-P値(近似法)は使用されておらず、そのためP値はやや保守的になり、検定結果が有意になりにくい傾向があります。Mid-P値は、観測された値の確率の半分と、それより極端な値の確率を加えることで、保守性を緩和し、検出力を高める目的で用いられます。
exact2x2() 関数(Rの exact2x2 パッケージ)
2×2分割表に対して超幾何分布に基づく正確な検定を行うための関数であり、tsmethod 引数により “central”(中央P値)や “midp”(Mid-P値)などのP値計算方法を選択できます。Mid-P値は、正確なP値に比べて保守性が低く、検出力(power)を高める効果がありますが、その分第一種の過誤(Type I error)のリスクが高まる可能性があるため、目的に応じた使い分けが重要です。
Fisher検定を使うべき場面
2×2表で、期待度数が5未満のセルがある場合
標本サイズが小さい場合
厳密な検定が求められる場合(例:医学研究、論文)
χ²検定を使うべき場面
標本サイズが大きく、期待度数が十分にある場合
探索的分析や迅速な検定が求められる場合
カテゴリ数が多い場合(例:3×3以上の分割表)
期待度数
Yes | No | 合計 | |
---|---|---|---|
Severe | A | B | A+B |
Mild | C | D | C+D |
合計 | A+C | B+D | N |
例えば「Severe × Yes」の期待度数は、E11=(A+B)×(A+C)NE11=N(A+B)×(A+C)。つまり、行合計 × 列合計 ÷ 総合計で求められます。

以下、ここではfisher.test()を使用した例を示します
fisher.test()を使用した実行例の紹介
Rの
fisher.test()
関数は、2×2分割表に対して正確な累積確率(central P値)を返しますが、離散分布の性質上、分布が左右非対称になることがあり、検定結果の解釈が難しくなる場合があります。exact2x2
パッケージのfisher.exact()
関数では、tsmethod = "central"
やtsmethod = "midp"
を選択できるため、検定の目的に応じてより柔軟な方法を選ぶことができます。
片側検定(上側),alternative = “greater”
> addmargins(tab)
effect
severity yes no Sum
severe 12 3 15
mild 6 8 14
Sum 18 11 29
対立仮説1 H1: オッズ比 > 1(severe グループのオッズが mild グループよりも大きい)。これは、重度群の効果ありの人数が12人以上になる確率を求める検定です。
fisher.test(tab, alternative = "greater")
Fisher's Exact Test for Count Data
data: tab
p-value = 0.04601
alternative hypothesis: true odds ratio is greater than 1
95 percent confidence interval:
1.029929 Inf
sample estimates:
odds ratio
5.003853
X≧12、つまりX=12, 13, 14, 15 となる確率を求めます。
P(X) = P(X≧12 | severe=15, mild=14, yes=18 ) という条件付き確率になります。
P(X=12) + P(X=13) + P(X=14) + P(X=15)=0.046
この確率は超幾何分布を使って求めます(後で出てきます)。
この検定は、片側検定(greater)であり、対立仮説は「真のオッズ比は1より大きい」です。p値が 0.046(< 0.05)であるため、重症群と軽度群の間に有意差があると判断され、重症群のオッズが有意に高いと結論づけられます。
- p-value(p値)= 0.046
このP値は、超幾何分布に基づいて、観測された分割表以上に極端な表が出る確率を正確に計算したもの(central P値)であり、Mid-P値(近似法)ではありません。 - alternative hypothesis(対立仮説): Rは対立仮説を出力します。ここでの対立仮説は、「真のオッズ比は1ではない」。すなわち・・・p値<0.05なので「重症群と軽度群には有意差があり、重症群のオッズは有意に高い」という結果になります。
- 95 percent confidence interval: 下記のオッズ比の95%信頼区間。
- オッズ比の推定値(5.003853)は、単純な割り算ではなく、条件付き最尤推定によって算出されています。詳細は奥村晴彦先生のページをご参照ください。
片側検定(下側),alternative = “less”
対立仮説2 H1: オッズ比 < 1(severe グループのオッズが mild グループよりも小さい)。これは、重度群の効果ありの人数が12人以下になる確率を求める検定です。
fisher.test(tab, alternative = "less")
Fisher's Exact Test for Count Data
data: tab
p-value = 0.9935
alternative hypothesis: true odds ratio is less than 1
95 percent confidence interval:
0.00000 29.77609
sample estimates:
odds ratio
5.003853
X≦12、つまり X=12, 11, 10, ・・・, 4 となる条件付き確率を求めます。
P(X≦12 | severe=15, mild=14, yes=18 )
=P(X=12) + P(X=11) + ・・・ + P(X=4)
=0.9935
p値は0.99なので帰無仮説が棄却できません。つまり、「severe グループのオッズが mild グループよりも低い」とは統計的には言えません。
両側検定, alternative = “two.sided”
対立仮説3 H1: オッズ比 ≠1(evere グループのオッズと mild グループのオッズは異なる)。severityのカテゴリー(severeとmild)とeffect(yesまたはno)の間における独立性の検定になります。
fisher.test(tab, alternative = "two.sided")
Fisher's Exact Test for Count Data
data: tab
p-value = 0.06043
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
0.8163182 40.7244582
sample estimates:
odds ratio
5.003853
P=0.06 なので有意差はありません。このp値は後半で説明します。