Topic 2
対応あり t 検定:介入前後の比較
Paired t-test with before-after visualization
同じ対象を介入前後で測定したときに、平均的な変化があるかを評価する基本テーマ。差分の考え方、前提条件、可視化、レポートの書き方までを一気通貫で学べます。
このページでは、R を使って「同じ人を2回測った」データを分析する一番基本的な方法である対応あり t 検定を扱います。初心者がつまずきやすい「対応あり/対応なし」の違い、wide 形式と long 形式の役割の違い、差分を見るという発想を、実際のサンプルデータと図を使って丁寧に確認できる構成にしています。
このページのゴール
- 対応あり t 検定が『差分の平均の検定』であることを理解する
- wide データから long データへ変換し、前後比較の図を描けるようになる
- t 値・自由度・p 値・95%信頼区間・平均差の読み方を理解する
- レポートや論文で使える日本語/英語の結果記述をそのまま応用できるようになる
Start here
まず押さえる3つのポイント
初心者向けの見取り図
- 前後比較で最初に見るべきなのは before と after の平均の差ではなく、各人の difference = after - before です。
- 正規性を確認するときも、before 列や after 列を別々に見るだけでは不十分で、difference 列の分布を確認するのが基本です。
- 図としては、各対象の変化を見せる折れ線プロットと、分布の位置と広がりを見せる箱ひげ図の組み合わせが分かりやすいです。
一番大事な考え方
初学者向けの最重要ポイントは『対応あり t 検定では差分が主役』という一点です。この理解があると、前提条件の確認も、図の読み方も、結果の書き方も一気に整理しやすくなります。
Basics
分析の概要と前提条件
どんなときに使うか
同一被験者の介入前後、研修前後、治療前後など、対応のある2条件の平均差を検討します。対応あり t 検定は『前後の平均を別々に比べる検定』ではなく、『各対象の差分の平均が0からずれているか』を検討する手法です。
必要なデータ形式:同じ対象に対して2回測定された連続変数データ。分析自体は wide 形式(before 列と after 列)で扱うと分かりやすく、図を描くときは long 形式(time 列と score 列)に変換すると便利です。
向いている場面
- 同じ参加者を介入前後で測定したとき
- 同じ学生の授業前後テストを比較したいとき
- 同じ製品を改良前後で測定したとき
別の方法を考える場面
- 比較する2群が別々の人・別々の対象なら、対応なし t 検定を使います
- 時点が3つ以上あるなら、反復測定 ANOVA や線形混合モデルを検討します
- 差分に強い外れ値や著しい非対称がある場合は、Wilcoxon の符号付順位検定も候補になります
差分を見る検定であることを数式で確認する
ここで d̄ は差分の平均、sd は差分の標準偏差、自由度は n - 1 です。
- 各対象について、前後が1対1に正しく対応づいていること
- 対象どうしは独立していること(同じ人の前後は依存していてよい)
- 検定で重要なのは『各人の差分』の分布であり、差分がおおむね対称・極端な外れ値が少ないこと
- 尺度は少なくとも間隔尺度として扱えること
Assumption check
前提条件はどう確認するか
対応あり t 検定では、before と after を別々に眺めるだけでなく、difference = after - before を作って確認するのが基本です。
1. まず差分列を作る
dat$diff <- dat$after - dat$before のように差分を明示的に作ると、分析の意味がぶれません。
2. ヒストグラムと QQ プロットを見る
差分の分布が大きく歪んでいないか、極端な外れ値がないかを視覚的に確認します。学術的にも、可視化と数値検定の併用が実務的です。
3. Shapiro-Wilk 検定は補助的に使う
shapiro.test(dat$diff) は参考になりますが、p 値だけで機械的に判断せず、標本サイズと図も合わせて解釈します。
4. 変化量の外れ値に注意する
1〜2人だけ極端に大きい変化があると、平均差や t 値に影響します。paired plot を見て、どの参加者が大きく動いたかを確認すると安心です。
Data structure
データの形をつかむ
分析では wide 形式、可視化では long 形式が分かりやすい、という流れをここで確認します。
wide 形式(検定向き)
1行が1人、before と after が別の列に入る形です。
| id | before | after | difference |
|---|---|---|---|
| 1 | 67.0 | 78.9 | +11.9 |
| 2 | 61.9 | 67.0 | +5.1 |
| 3 | 68.2 | 74.5 | +6.3 |
| 4 | 75.2 | 75.5 | +0.3 |
| 5 | 61.1 | 64.9 | +3.8 |
| 6 | 61.1 | 67.6 | +6.5 |
long 形式(ggplot2 向き)
1行が1観測で、time 列に before / after を入れる形です。
| id | time | score |
|---|---|---|
| 1 | before | 67.0 |
| 1 | after | 78.9 |
| 2 | before | 61.9 |
| 2 | after | 67.0 |
| 3 | before | 68.2 |
| 3 | after | 74.5 |
サンプルデータの要約統計
| 時点 | n | 平均 | SD | 中央値 |
|---|---|---|---|---|
| 介入前 | 20 | 61.62 | 7.68 | 61.50 |
| 介入後 | 20 | 66.56 | 8.04 | 67.30 |
| 差分 (after - before) | 20 | 4.94 | 3.87 | 5.10 |
R code
Rコードを順番に実行する
library(tidyverse)
# 付属のサンプルデータを読み込む
dat <- read.csv("sample-data/sample_paired_t_scores.csv")
# 差分を作る:対応あり t 検定ではここが主役
dat <- dat %>%
mutate(diff = after - before)
# 要約統計
dat %>%
summarise(
n = n(),
mean_before = mean(before),
sd_before = sd(before),
mean_after = mean(after),
sd_after = sd(after),
mean_diff = mean(diff),
sd_diff = sd(diff)
)
# 図用に long 形式へ
dat_long <- dat %>%
pivot_longer(
cols = c(before, after),
names_to = "time",
values_to = "score"
)
# 対応あり t 検定
tt <- t.test(dat$after, dat$before, paired = TRUE)
tt
# 差分の確認:ヒストグラムや QQ プロットと合わせて見る
shapiro.test(dat$diff)
# 効果量の導入として Cohen's d_z を手計算
d_z <- mean(dat$diff) / sd(dat$diff)
d_z
# 参考:effectsize パッケージを使う場合
# install.packages("effectsize")
# library(effectsize)
# cohens_d(dat$after, dat$before, paired = TRUE)
library(ggplot2)
# 1) 各対象の変化を見せる折れ線プロット
ggplot(dat_long, aes(x = time, y = score, group = id)) +
geom_line(color = "#b8c4d8", linewidth = 0.7) +
geom_point(aes(color = time), size = 2.5) +
stat_summary(aes(group = 1), fun = mean, geom = "line", linewidth = 1.1, color = "black") +
stat_summary(aes(group = 1), fun = mean, geom = "point", size = 3, color = "black") +
labs(x = NULL, y = "Test score", title = "Before-after change by participant") +
theme_minimal(base_size = 13) +
theme(legend.position = "none")
# 2) 分布を見せる箱ひげ図
ggplot(dat_long, aes(x = time, y = score, fill = time)) +
geom_boxplot(width = 0.55, alpha = 0.65, outlier.shape = 21) +
geom_jitter(width = 0.08, alpha = 0.65, size = 2) +
labs(x = NULL, y = "Test score", title = "Distribution before and after the intervention") +
theme_minimal(base_size = 13) +
theme(legend.position = "none")
# 主な出力のイメージ
# Paired t-test
# data: dat$after and dat$before
# t = 5.71, df = 19, p-value = 1.68e-05
# alternative hypothesis: true mean difference is not equal to 0
# 95 percent confidence interval:
# 3.13 6.75
# sample estimates:
# mean difference
# 4.94
# d_z
# [1] 1.28
Interpretation
出力の読み方
paired t-test の出力は長く見えますが、最初は「平均差・t 値・自由度・p 値・95%信頼区間」の5点を順番に読めれば十分です。
mean difference = 4.94
介入後 - 介入前 の平均差です。平均的には 4.94 点だけ上昇したことを表します。
読み方のヒント:前後それぞれの平均だけでなく、差分の平均として読むのが対応あり t 検定のコアです。
t(19) = 5.71
差分平均が 0 からどれだけ離れているかを、差分のばらつきで割って標準化した値です。自由度 19 は n - 1 に対応します。
読み方のヒント:n = 20 人なら自由度は 19、という対応を確認すると理解が深まります。
p < .001
差分平均が 0 という帰無仮説のもとで、今回のデータ以上に極端な結果が出る確率が非常に小さいことを示します。
読み方のヒント:p 値だけで結論を書かず、平均差と信頼区間も一緒に示すのが学術的には望ましいです。
95% CI [3.13, 6.75]
母平均差の妥当な範囲が 3.13 点から 6.75 点あたりにあると見積もられることを示します。
読み方のヒント:区間に 0 が含まれていないので、差がないとは言いにくいと判断できます。
d_z = 1.28
差分の平均を差分の標準偏差で割った標準化効果量です。前後差の大きさを、ばらつきに対して相対化して示します。
読み方のヒント:対応ありデザインでは複数の標準化方法があるので、使った指標名(ここでは d_z)を明記すると親切です。
Figure
図の読み方
図1 介入前後のテストスコアの変化。左は各参加者の前後を線で結んだ折れ線図、右は前後それぞれの分布を示す箱ひげ図。
どこを見るとよいか
- 左図では、多くの線が右上がりで、介入後にスコアが上がった参加者が多いことが分かります。
- 右図の箱ひげ図では、介入後の中央値と全体の位置が高く、分布全体が上方向にシフトしています。
- ただし全員が同じだけ改善しているわけではなく、変化量には個人差があります。これを見せられるのが paired plot の強みです。
Writing
レポート用の結果記述例
Japanese / simple
初学者向けの書き方
20名の参加者について介入前後のテストスコアを比較したところ、介入後のスコアは介入前より有意に高かった(介入前: 61.62 ± 7.68点、介入後: 66.56 ± 8.04点、平均差 = 4.94点、95%CI [3.13, 6.75]、対応あり t 検定、t(19)=5.71, p < .001)。図1より、多くの参加者でスコアが上昇していることが確認できた。
Japanese / academic
やや学術寄りの書き方
同一参加者を対象とした介入前後比較の結果、介入後得点は介入前得点より有意に高かった(介入前: M = 61.62, SD = 7.68;介入後: M = 66.56, SD = 8.04;平均差 = 4.94, 95% CI [3.13, 6.75], paired t-test, t(19) = 5.71, p < .001, d_z = 1.28)。対応のある折れ線図では、多くの参加者で得点の上昇が観察され、介入効果は参加者レベルでも概ね一貫していた。
English
Report writing example
A paired t-test comparing test scores before and after the intervention showed that post-intervention scores were significantly higher than pre-intervention scores (before: M = 61.62, SD = 7.68; after: M = 66.56, SD = 8.04; mean difference = 4.94, 95% CI [3.13, 6.75], t(19) = 5.71, p < .001, d_z = 1.28). Figure 1 shows that most participants improved after the intervention, although the magnitude of change varied across individuals.
Caption
図キャプション例(日本語)
図1 介入前後のテストスコアの変化。左は各参加者の前後を線で結んだ折れ線図、右は前後それぞれの分布を示す箱ひげ図。
Checklist
最低限書いておきたい項目
- 介入前・介入後の平均±SD を書く
- 平均差と 95%信頼区間を書く
- t 値、自由度、p 値を書く
- 必要に応じて効果量(d_z など)を書く
- 図では『どの程度の人が上がったか』と『分布全体の位置』を言葉で補足する
Common pitfalls
初心者がつまずきやすい点
対応なし t 検定を使ってしまう
同じ人を2回測っているのに独立2群として扱うと、対応の情報を捨ててしまいます。前後が1対1で結びつくなら paired = TRUE を基本線にします。
before と after の正規性だけを見て安心してしまう
対応あり t 検定で重要なのは差分の分布です。before と after がそれぞれきれいでも、difference に強い歪みや外れ値があれば注意が必要です。
欠測の扱いでペアがずれる
片方だけ NA の行を雑に落とすと、before と after の対応が壊れることがあります。ID を残したまま処理し、必要なら complete.cases() でペア単位に確認します。
p 値だけを書いて終える
実務でも学術でも、平均差と信頼区間を書くと結果の大きさが伝わりやすくなります。可能なら効果量も併記します。
FAQ
よくある質問
Q. 介入前と介入後のそれぞれが正規分布なら十分ですか?
A. 十分ではありません。対応あり t 検定では、介入後 - 介入前の差分ベクトルの分布を確認するのが基本です。ヒストグラム、QQ プロット、必要に応じて Shapiro-Wilk 検定を組み合わせて判断します。
Q. wide 形式と long 形式のどちらが正しいですか?
A. どちらも使います。検定自体は before 列と after 列を直接渡せる wide 形式が分かりやすく、可視化では time 列を持つ long 形式の方が ggplot2 と相性が良いです。
Q. 対応あり t 検定の p 値が有意なら、全員が改善したと言えますか?
A. そこまでは言えません。有意差は『平均的には差がある』ことを示すだけです。個人差の有無は paired plot を見て補足すると誤解が減ります。
Q. サンプルサイズが小さいときはどうすればよいですか?
A. 差分の可視化をより丁寧に行い、外れ値や歪みの影響を確認します。差分がかなり偏っている場合は、Wilcoxon の符号付順位検定も候補になります。
代替手法
代替手法・次の一歩
研究課題やデータ構造が少し変わると、選ぶべき手法も変わります。このテーマを土台にしつつ、どの条件で別の方法へ進むかを押さえておくと、分析計画が立てやすくなります。
Wilcoxon の符号付順位検定
差分の分布が強く歪んでいる、または極端な外れ値の影響が大きいときの代表的な代替法です。R では wilcox.test(x, y, paired = TRUE) を使います。
反復測定 ANOVA / 線形混合モデル
前・中・後のように3時点以上あるときは、対応あり t 検定を繰り返すより、時点全体を扱えるモデルの方が自然です。
差分の回帰分析
介入量や背景変数によって改善幅が変わるかを知りたい場合は、difference を目的変数にした回帰モデルも検討できます。
参考資料
参考資料
このページの説明は、R 本体の公式ドキュメント、NIST の統計ハンドブック、tidyverse/ggplot2 の公式リファレンスを軸に整理しています。
- R Core Team: t.test() documentation
- NIST/SEMATECH e-Handbook: Analysis of paired observations
- R Core Team: shapiro.test() documentation
- R Core Team: qqnorm() / qqline() documentation
- tidyr: pivot_longer() reference
- ggplot2: geom_boxplot() reference
- ggplot2: geom_path() / geom_line() reference
- effectsize vignette: standardized differences for paired samples
運営と利用上の注意
このページの位置づけ
本サイトのトピックページは、Rによるデータ分析の学習支援とレポート作成の補助を目的としたオリジナル解説です。サンプルデータとコードは再現練習用に作成しているため、実データを扱う際には研究計画・前提条件・欠測・外れ値・尺度水準をあらためて確認してください。
編集方針
ページ本文は、標準的な統計手法、Rの公式ドキュメント、一次資料に近い参考文献を優先して整理しています。更新や訂正の方針は編集方針ページで公開しています。