Rの関数:wilcox.test {stats}:ウィルコクソンの符号順位検定(対応あり2標本の場合)

Rの関数から wilcox.test {stats}:ウィルコクソンの符号順位検定 / Wilcoxon Signed Rank Test を確認します。

本ポストはこちらの続きです。

Rの関数:wilcox.test {stats}:ウィルコクソンの符号順位検定(1標本の場合)
const typesetMath = (el) => { if (window.MathJax) { // MathJax Typeset window.MathJax.typeset(); } else if (window.katex...

ウィルコクソンの符号順位検定 / Wilcoxon Signed Rank Test

シミュレーションコード

「教育プログラムの実施前後」のようなシナリオを想定し、個体ごとの変化(差分)に注目した場合、検定がどのように差を検出するかを可視化・検証する 対応あり2標本ウィルコクソン符号順位検定のシミュレーション です。

なお、有意水準は5%とします。

# パッケージの読み込み
library(ggplot2)
library(tidyr)

# 乱数シードの固定
seed <- 20260125
set.seed(seed)

# 対応のある2標本ウィルコクソン符号順位検定のシミュレーション

# 1. サンプルデータの生成
# シナリオ: あるトレーニングの効果測定(事前 vs 事後)
n_pairs <- 20

# 事前データ (Pre): 平均60、標準偏差10の正規分布
pre_data <- rnorm(n_pairs, mean = 60, sd = 10)

# 真の効果 (Effect): 全体として +5.0 の上昇効果があるとする
true_effect <- 5.0

# 事後データ (Post): 事前データ + 真の効果 + 個体ごとのバラつき(ノイズ)
# 「対応あり」とは、PreとPostに相関があることを意味します。
post_data <- pre_data + true_effect + rnorm(n_pairs, mean = 0, sd = 2)

# データフレームの作成(可視化用)
df_paired <- data.frame(
  ID = factor(rep(1:n_pairs, 2)),
  Time = factor(rep(c("事前", "事後"), each = n_pairs), levels = c("事前", "事後")),
  Score = c(pre_data, post_data)
)

# データの可視化
# 「対応のあるデータ」の可視化には、箱ひげ図よりも
# 個体ごとの変化をつないだスロープチャート(Parallel Coordinate Plot)が適しています。
p1 <- ggplot(df_paired, aes(x = Time, y = Score)) +
  # 個体ごとの変化線
  geom_line(aes(group = ID), color = "gray60", alpha = 0.7) +
  # 点の描画
  geom_point(aes(color = Time), size = 3) +
  # 平均値の変化(赤線)
  stat_summary(
    fun = mean, geom = "line", aes(group = 1), color = "red",
    linewidth = 1.2, linetype = "dashed"
  ) +
  scale_color_manual(values = c("事前" = "blue", "事後" = "darkgreen")) +
  labs(
    title = "個体ごとのスコア変化(事前 vs 事後)",
    subtitle = "灰色の線が右上がりであれば、その個体はスコアが上昇している。\n赤点線は全体の平均的な推移を示す。",
    x = "時点",
    y = "スコア"
  ) +
  theme_minimal()

print(p1)

cat("--- データ概要 ---\n")
cat(sprintf("ペア数: %d 組\n", n_pairs))
cat(sprintf("真の上昇効果: +%.1f\n", true_effect))


# 2. 検定の実行
# paired = TRUE を指定することで、対応のある検定を実行します。
# 内部的には「差分 (x - y)」に対して1標本検定を行っているのと同義です。
test_res_paired <- wilcox.test(pre_data, post_data, paired = TRUE, conf.int = TRUE)

# 結果の表示
cat("\n--- 検定結果 ---")
print(test_res_paired)
--- データ概要 ---
ペア数: 20 組
真の上昇効果: +5.0

--- 検定結果 ---
    Wilcoxon signed rank exact test

data:  pre_data and post_data
V = 0, p-value = 1.907e-06
alternative hypothesis: true location shift is not equal to 0
95 percent confidence interval:
 -6.318922 -3.904082
sample estimates:
(pseudo)median 
     -5.182321 
Figure 1

統計量 V = 0 の意味

この \(V\) は「ウィルコクソンの符号付き順位統計量」です(V = 0)。

コードでは、paired = TRUE の場合、Difference = Pre - Post を計算し、「差が正(プラス)になったものの順位和」\(V\) として出力します。

  • \(V = 0\) ということは、正の差(Pre > Post)が一つもなかったことを意味します。
  • つまり、全てのペアにおいて「Pre < Post」であった(全員のスコアが上がった)ことを示しています。

推定値 (pseudo-median)

差分(Pre - Post)の中央値の推定値は 約 -5.18 です((pseudo)median : -5.182321)。

シミュレーション設定で true_effect = 5.0(つまり Post は Pre より 5 大きい)としたため、Pre - Post は理論上 -5.0 になります。

この推定値は真の値(-5.0)と近く、シミュレーション通りの効果を検出できています。

p値による判定

p値は 約 0.0000019 と設定した有意水準を下回っており(p-value = 1.907e-06)、「差の中央値は0である」という帰無仮説は棄却されます。

信頼区間

差分の95%信頼区間は [-6.32, -3.90] です(95 percent confidence interval: -6.318922 -3.904082)。

区間全体が負の領域にあり、0を含んでいません。これは「統計的に有意にマイナスである(=事後の方が有意に大きい)」ことを示しています。

以上です。