【R言語】ggplot2を使って3群以上の比較グラフを作る④〜ggsignifでp値を入れる準備をする〜
こんにちは。R言語の勉強真っ最中の生命科学系研究者のえいこです。
グラフを作るとアルファベット順に並べてしまうRの特性と悪戦苦闘しながら、X軸の変数を制御して思い通りの順番に並べられるようになりました。
さて、おそらく最難関になるのではないかと予想される「検定結果をグラフに書いていく」をしていきたいと思います。
あまり複雑なことをせずに、pの値を直接書いてしまえ!スタンスでいきたいと思います。
(スターの数とpの値を両方書いているとごちゃごちゃになるので...Nature, Cell, Scienceに出ている論文を見るとpの値を記入しているものが多くなってきているるのでpの値を書いておけば間違いない。)
◇
“ggsignif”ってどうやって使うんだっけ?
二群検定の時に使っていましたが、どうやって使うんだったかすっかり忘れてしまいました。
自分の書いた記事で復習します。
ほー!複雑なことしてますね...
一つ一つ見ていくと...
・geom_signifという関数を使う
・xの場所やyの場所を指定している
・スターを書き込むのにif文を使っている
・下向きの線を入れるのに”tip_length”を使っている
多群比較の場合はどうなるんでしょう?
ggsignifを使って多群比較しているコードを探してみましょう。
やりたいことは、こんな感じ。(中身は英語なので注意してください。翻訳するとへんな日本語が出てきます)
このサイトでやっていることはIrisのデータを使って花弁の長さと額の長さを比較しているグラフを書いています。
で、geom_signifを使っているコードを見てみると...
geom_signif(comparisons =list(c("setosa", "virginica"),
c('setosa','versicolor'),
c('virginica','versicolor')),
step_increase = 0.1)
やっていることは、
・引数comparisonに比較する組み合わせのリストを渡す
・step_increaseを入れて重ならないようにしている
これだけで、x軸もy軸も指定しないで書き込めるんだったら楽チンですね。
step_increaseは後からでもなんとでもなりそう。
ということで、引数comparisonに渡すための組み合わせリストを作っていきましょう。
◇
比較する群のリストを作る
まずはこのリストを既に作っているもののどこから引っ張ってくるかが大事。
検定の結果のフォーマットを全て統一したものを作って、”df”という変数に入れているのでここから取ってくればよいのでは?とちょっと検討してみましょう。
比較する群、pの値、星の数が書いてある完璧な表なのです。が、引数comparisonにそのまま渡せません。
なぜなら、”a:b”と文字列がくっついてしまっているから....
なんとかしてバラせないものかと思って調べてみました。で、たどり着いたのがRjpWiki。
「文字列のベクトル要素を与えられたパターンに従って分解」で”strsplit”関数を使っています。
関数の形はstrsplit(対象文字列, 分割する区切り)。分割する区切りは”:”で行けそうですね。
ちょっとやってみましょう。
strsplit(df[1,1], “:”)
を実行してみると...
エラーが出ました。non-character だよと...確かfactor型だったかも...
class関数で確認してみます。
やはりfactor型でした。ということは、”as.character”で変換しないとダメですね。
strsplit(as.character(df[1,1]), “:”)
分解できました!要素を取り出せるか試してみましょう。
打ってみたコードはこちら
stsplit(as.character(df[1,1],”:”)[1] #一個目の”a”が出るかなと期待
strsplit(as.character(df[1,1],”:”)[[1]][1]
二行目のコードで”a”だけが取り出せるので、“b”を取り出すには
strsplit(as.character(df[1,1], “:”)[[1]][2]
で取り出せそうです。これをベクトルの形に収めればOK!(for文を使えば行けそうですね。
◇
for文を使ってリストを作っていく
まずは比較用の空リストを作っておいてfor文を書いていきましょう。
#geom signif parameters
#comparison pair
comp<-list()
for (i in 1: nrow(df)){
df1<- c(strsplit(as.character(df[i,1]),":")[[1]][1],
strsplit(as.character(df[i,1]),":")[[1]][2])
comp<- c(comp, list(df1))
}
これで”comp”を実行すると...
これで、signifに渡す比較の組み合わせリストが完成しました!
これ作るのに少し試行錯誤がありまして...
◇
for文でリストを作る失敗談
最初は、
comp<-list()
for (i in 1: nrow(df)){
df1<- c(strsplit(as.character(df[i,1]),":")[[1]][1],
strsplit(as.character(df[i,1]),":")[[1]][2])
comp<- list(comp, df1)
}
こんな風に書いていたんです。違いがお分かりでしょうか?
for文でベクトルに入れていくのは、comp<- c(comp, df1)で併記できるのは分かっていたので(下の様になる)
リストにしていくんだから、リストで良いだろうということで書いていたのですが...
わわわ....[[1]][[1]][[1]]のオンパレード...
欲しいリストの形をもう一度確認。
list(c("a", "b"),c('a','c'),c('b','c'))
[[1]]のオンパレードとかにならないですよね...
で、for文でのリストの作り方をもう一度確認しました。
リストの要素を追加していく時には、”list()”の形で囲わないとどんどんリストの要素が深くなってしまうそうです。で、
comp<- c(comp, list(df1))
という形になりました。
◇
リストを作るのに一苦労...
次回こそはグラフにpの値を入れていきたいと思います。
それでは、また!
最後までお読みいただきありがとうございます。よろしければ「スキ」していただけると嬉しいです。 いただいたサポートはNGS解析をするための個人用Macを買うのに使いたいと思います。これからもRの勉強過程やワーママ研究者目線のリアルな現実を発信していきます。