3 ノンパラ対応あり
今回は、反復測定のデータで同一個体を線で結ぶグラフを描きます。
その際、dotと線を群ごとに色分けをします。
ただ、このやり方だと、いわゆる二元配置のデータということになりますが、ノンパラ版の二元配置以上の分散分析に変わる検定は一般的には知られていませんので、ここでは繰り返しのある一元配置分散分析の状況で用いるノンパラ検定(フリードマン検定)を、統計としては行います。
https://scrapbox.io/files/63879913b31230001d97a290.png
こんなグラフになります。僕は、こういうグラフを自由自在に無料で描けるようになりたいと思い、Rを始めました。
scriptは以下です。
code:r
# ---------- preparation in advanca 事前準備--------------------------------------------------
# Install packages if not installed 必要なパッケージが無けれな自動でインストール-----
if(!require("tidyverse")) install.packages("tidyverse")
if(!require("dplyr")) install.packages("dplyr")
if(!require("ggplot2")) install.packages("ggplot2")
if(!require("exactRankTests")) install.packages("exactRankTests")
# clear R's brain 一度参照したリストもしくは変数を次の作業で消す-----
rm(list = ls())
# Load libraries 必要なパッケージの読み込み-----
library(tidyverse)
library(ggplot2)
library(exactRankTests) #needed fo Exact Rank Tests # Data input 今後以下のパスからデータを自動で読み込みする場合-----
library(readr)
CanRsample <- read.csv(file.choose()) #Run and choose CanRsample2021.csv CanRsample_tidy <- gather(CanRsample, key = "Season", value = "aveTemp", aveTemp_SpAut, aveTemp_summer, aveTemp_winter)
# # ----------prep done 準備だん------------------------------------------------------------
# 【3】box plots within 箱ひげ図 個体内----------------------------
oneway_within <-matrix(c(CanRsample$aveTemp_SpAut, CanRsample$aveTemp_summer, CanRsample$aveTemp_winter), ncol = 3)
friedman.test(oneway_within)
pairwise.wilcox.test(CanRsample_tidy$aveTemp, CanRsample_tidy$Season, paired=T, correct=F, exact=F, p.adj="holm")
wilcox.test(CanRsample$aveTemp_SpAut, CanRsample$aveTemp_summer, paired=T, correct=F, exact=F, p.adj="holm")
wilcox.exact(CanRsample$aveTemp_SpAut, CanRsample$aveTemp_summer, paired=T, correct=F, exact=F, p.adj="holm")
scale_x_discrete(limit=c('aveTemp_SpAut', 'aveTemp_summer', 'aveTemp_winter')) +
geom_line(aes(group = ID_town, colour = place), alpha = 0.5) +
geom_point(size = 4, aes(colour = place), alpha = 0.7) + #alphaはdotの透明度 scale_fill_manual(values = c (Sendai = "deepskyblue3", Tokyo = "gray1", Kagoshima = "orange" )) +
scale_color_manual(values = c (Sendai = "deepskyblue3", Tokyo = "gray1", Kagoshima = "orange" )) +
ggtitle("【3】box plots within 箱ひげ図 個体内") +
theme_classic(base_size = 18, base_family = "HiraKakuProN-W3") # white backgrond グラフの背景を白に
【データ整形】
今回は、フリードマン検定の後検定での多重比較を行うために、横長データ(ワイド型)を縦長データ(ロング型)に変える必要があります。フリードマン検定のデータ指定の方法と、多重比較に使う pairwise.wilcox.test() のデータ指定の方法が異なるのです。また、グラフを描く際も、ロング型である必要があります。
このデータ整形で活躍するのが、tidyverse というパッケージです。データ整形で大変重宝されています。
いつものようにデータファイルのcsvを読み込むscriptの後に、今回は以下のように書いてあります。
code:r
CanRsample_tidy <- gather(CanRsample, key = "Season", value = "aveTemp", aveTemp_SpAut, aveTemp_summer, aveTemp_winter)
gather() という関数を使っています。
この関数の使い方とデータの並び替えは、以下のサイトなどでイメージを持ってもらうと分かりやすいと思います。
ロング型のデータでは同一個体/被験者のデータが複数の行に別れることになります。で、色んな関数で「IDが同一なら同一個体である」みたいな指定をすることで、グラフに線を引いたりすることが可能になります。
【統計:Friedman's testとWilcoxon signed rank test】
フリードマン検定は、データの指定の仕方だけ、若干面倒です。最初に使用するデータマトリックスを作ってあげないといけません。スクリプト中では、
oneway_within <-matrix(c(CanRsample$aveTemp_SpAut, CanRsample$aveTemp_summer, CanRsample$aveTemp_winter), ncol = 3)
ここでは、matrixという関数を使って、ワイド型データのCanRsampleの中から、横並びで記載している3つの季節のデータを抽出しています。最後に、ncol = 3 で、3回の反復であることを指定しています。このようにまとめたデータを、oneway_within というオブジェクトにしています。
ここまでくると、フリードマン検定は簡単で、friedman.test(使用するデータのオブジェクト)というカタチで指定して実行すればOKです。今回の検定の結果は有意になります。
多重比較では、ペアワイズな検定の関数を用います。
pairwise.wilcox.test(使用するロング型データ$従属変数, 使用するロング型データ$条件となる独立変数, paired=T, correct=F, exact=F, p.adj="holm")
のように書きます。ここで使うデータは、先ほど作っておいたロング型データの CanRsample_tidy です。
対応のある2条件間の比較のノンパラは、ウィルコクソンの符号付き順位検定(Wilcoxon signed rank test)です。符号付き順位"和"検定と、和をつけている訳も見受けられますが、これは間違いじゃないかなと僕は思ってます。対応ない検定の名前と並べると
ウィルコクソンの順位和検定(Wilcoxon rank sum test):対応のない2群間のノンパラ検定、U検定と同じ結果が出る(2 ノンパラ対応なし群間差参照) ウィルコクソンの符号付き順位検定(Wilcoxon signed rank test):対応のある2条件間の比較の検定
というように、英語の名称で、sum(和)の有る/無し に違いがあります。
統計のスクリプトの最後に、2条件間でウィルコクソンの符号付き順位検定を実行するスクリプトの例も書いてあります。
Friedman's testとWilcoxon signed rank testは、等分散性の問題を気にしなくて良いので、使い勝手が良いと思っています。ノンパラですから、正規性を仮定しなくて良いので、事前に分布を見る(これ自体に検定を繰り返すことで起るたType 1 error の危険がある)必要もなく、統計の面から見れば、安定した実験デザインになると言えます。なので、最近僕は、なるべく反復測定の実験デザインにして、個体内での変化として実験の効果を検討できるように計画をすることが多いです。
【グラフの描画】
用いるデータ形式
これまでのページで行ってきたグラフ描画とかなり違いので、それらとの相違点だけ触れていきます。
同一個体のデータに線を引く場合は、用いるデータはロング型になるので、ここでは、tidyversのgather()で作った、CanRsample_tidyをデータとして指定します。
ボックスプロット
ノンパラはボックスプロットで描くことにしているので、
geom_boxplot()
を使っています。
同一個体のデータに線を引く
geom_line()という関数を使います。知ってしまえば大したことはないのですが、、、Rを勉強し始めた初期に結構書き方に手間取った印象です。ポイントは以下のように、
geom_line(aes(group = ID_town, colour = place), alpha = 0.5)
geom_line(aes(group = 個体IDなど, colour = 群の名前の独立変数), )のように指定することです。
ドットの描き方
線とdotを接続させるためには、geom_jitterを使うと見辛くなるので(描画自体は出力される)、geome_pointを使いましょう。
【色分けが不要な場合】
条件間の違い(横軸に書かれた独立変数の違い)さえ分かれば良いので「色などいらん」という方向けに、モノクロで描く際のスクリプトも以下に置いておきます。
https://scrapbox.io/files/63879920ce8b55001f03109d.png
code:r
ggplot(CanRsample_tidy, aes(x = Season, y = aveTemp)) +
geom_line(aes(group = ID_town), color = "grey", alpha = 0.5) +
ggtitle("【3_2】Fig_boxplot_withinMono 線とdotもモノクロver") +
theme_classic(base_size = 18, base_family = "HiraKakuProN-W3") # white backgrond グラフの背景を白に