ラベル R の投稿を表示しています。 すべての投稿を表示
ラベル R の投稿を表示しています。 すべての投稿を表示

2014年10月26日日曜日

ggplotを使ったfor文で項目名を順番に変えていく

ggplot2でグラフを描く時に、データに使う項目名(具体的にはcsvの列名)を変えて同じ体裁のグラフを複数いっぺんに描きたいときがあって、調べてたら出来るようになったのでメモ。
(追記)reshapeパッケージのmelt.data.frameを使うほうが簡単かも。後述します。

例としてirisを使います。

names(iris) 

とすると、当然
 
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species" 

と表示されます。
ここで、x軸をSpeciesにして、y軸用データを"Sepal.Length" "Sepal.Width" "Petal.Length"にして、それぞれの項目でボックスプロットにしたグラフを描くことを目的とします。

aes_stringを使う方法

まず、使いたい項目名をxnamに入れます(xnamは任意)。
 
xnam<-c("Sepal.Length","Sepal.Width","Petal.Length")

ggplot関数で作図したプロットを入れるリストをつくります。
plots<-list()

通常のggplot関数ですと、aes()でx軸用データ、y軸用データを設定するのですが、変数にした文字列を読み込みたいとき(つまり、Sepal.Lengthを読み込みたいためにxnam[1]と書きたいとき)に aes(x=Species,y=xnam[1]) と書くと正しく描画されません。
したがって、aes_string()を使います。ただし、ここで注意が必要なのは、
 
aes(x=Species, y=Sepal.Length) 

で良かった指定が、
aes_string(x="Species", y="Sepal.Length") 

みたいにダブルコーテーションで囲ってやらないとダメなのです。
ということで、あとは以下のようにfor文を書きます。
 
j <- 1
for (i in 1:length(xnam)) {
    plots[[j]]<-ggplot(iris, aes_string(x="Species",y=xnam[i])) + geom_boxplot()
    j <- j+1
  }

  これで3つのプロットが出来たわけですが、1枚にいっぺんに描くには次のように書きます。
 
args <- c(plots, list(ncol=3, nrow=1))
do.call(grid.arrange, args)
grid.arrangeはgridExtraパッケージの関数です。問題なく実行されると以下の様なグラフが出力されるはずです。
なおargs, do.callの書き方は以下のサイトを参考にさせていただきました。多謝!
R - 可変長引数が最初にある関数に対する do.call() のやりかた - Qiita


(追記)melt.data.frameを使う方法

reshapeパッケージの関数です。超便利。
install.packages("reshape")
library(reshape)
iris2 <- iris[,-4] #Petal.Widthを削除(上の例に合わせてます)
iris2.melt <- melt.data.frame(iris2,id.vars="Species",variable_name="Region")
実行してやると、ほらこの通り。魔法みたい。
> head(iris2.melt)
  Species       Region value
1  setosa Sepal.Length   5.1
2  setosa Sepal.Length   4.9
3  setosa Sepal.Length   4.7
4  setosa Sepal.Length   4.6
5  setosa Sepal.Length   5.0
6  setosa Sepal.Length   5.4
列名のvalueはデフォルトで決まっているようなので後で変えたいときは以下のようなのを。
names(iris2.melt) <- c("Species","Region","Length")
で、プロット。
ggplot(iris2.melt,aes(Species,Length)) + geom_boxplot() + facet_wrap(~Region, scales="free_y") 
結果はこんな感じ。
以下を参考にさせていただきました。
data.frame を ggplot2 用に加工する - joker8phoenix's diary

2015年4月16日追記:reshapeで感動していたのも束の間、時代はreshape2を通り越して、tidyr + dplyr を使おうってことになっているらしい。時代にまったくついて行けてない初心者です。
参考:http://meme.biology.tohoku.ac.jp/students/iwasaki/rstats/reshape2.html

2013年11月1日金曜日

[自分用] Rの基本

久しくRを触ってなかったんですが論文執筆のために触ることになり、何からすれば良いのかも戸惑う始末。なのでダメな自分用にメモっておきます。随時追加するかも。
ちなみに私のRの使用目的はグラフを作るのがメインです。あくまで自分用なので、「基本」と書きつつも私がよく使うものだけを列記します。

Rstudio立ち上げましょう

まずはここから。

CSV読み込みましょう

d <- read.csv("path to file", header = T or F) ワークディレクトリはデフォルトではホームフォルダに設定されてる。変更したければRstudioの環境設定から変える。<注意:csvファイルのカンマ区切りはスペースを含まないようにする。スペースも文字としてカウントされてしまうため。>
以下、データはこんなのを想定してます。

Species Season Value
A Spring 12
A Summer 36
B Spring 41
B Summer 19

特定の行または列だけ選びたければ

d[1,] (行)
d[,1] (列)

行とか列を削除したいときは

d[,-c(2,3,4)] #(2,3,4列目を削除)

オブジェクトの削除

a, b, cという3つのオブジェクトを一度に消す rm(a,b,c) 

条件からデータを抽出

例えば季節(Season)がSpringのデータだけ抽出したい、とか。 d.spring <- subset(d, Season=="Spring")

データの取り出し方いろいろ

説明しにくいので、読んで分かれ自分。
#ベクトル作成
> v<-c(2,3,4,5,6)

#普通に表示
> v
[1] 2 3 4 5 6

#2で割って余りが0になる=TRUE
> v%%2==0
[1] TRUE FALSE TRUE FALSE TRUE

#TRUEになるデータだけピックアップ
> v[v%%2 ==0]
[1] 2 4 6

#TRUEのデータが何番目かを表示
> which(v%%2==0)
[1] 1 3 5

#1,3,5番目のデータをピックアップ、二つ上のコードと結果は同じだけど。
> v[which(v%%2==0)]
[1] 2 4 6

とりあえずplotしてみる

plot(x,y,…) という書き方なので以下だとX軸にdのSeason、Y軸にdのValueが表示されます。 plot(d$Season, d$Value, main="title of figure") ちなみに、タイトルが長すぎて改行を入れたい場合は、 main="title of figure\nsubtitle" のように改行したいところに\nを入れれば、"title of figure" と "subtitle"の間に改行が入る。
※Macの場合。Windowsでは¥nを入れる。

x軸の項目名が1,2,3...とかなってるけど任意の名前にしたいとき

plot(data, xaxt="n") とxaxtパラメータでx軸の名前を入れないようにして一旦描画。次に、 axis(side=1, at=c(1:n), labels=LabelName) としてx軸に上書き。sideパラメータは1:下,2:左,3:上,4:右。atはx軸の項目数。その数と同じだけのLabelNameを先に作っておいて、x軸の項目名を置き換えるわけです。このLabelNameは文字列(character)でもベクターでもOKなようです。ここで、項目名が長いために90度回転させたいならlasというパラメータを入れる。こちらの有り難いページによれば以下とのこと。
可能な値は 0 (標準・軸に平行), 1 (x軸,y軸とも水平), 2 (x軸,y軸とも軸に垂直),3 (x軸,y軸とも垂直(半時計回りで90度回転)) の4つ
axis(side=1, at=c(1:n), labels=LabelName, las=3)

ヒストグラムも描いてみようかな

hist(d$Value)

ggplot2てパッケージがあったよな、たしか

インストール(初回だけで良い) install.packages("ggplot2") 読み込み library("ggplot2")

ggplot2でもプロットしてみる

qplot(data=hoge.rule1, Season, Value, main="title of figure") 分類(Species)に基づいて色分けしたいときは
qplot(data=hoge.rule1, Season, Value, main="title of figure", color = Species)

ggplot2は + で表現を追加できる

facet_wrapで複数のプロットを一度に描ける。以下の例では種ごとにプロットを作成。scalesで軸の範囲を設定可能
+ facet_wrap( ~ Species, scales = "free_y")   レイヤーの発想で点を重ねることも可能。以下の例ではsizeが3の点の上に、sizeが1.5の薄いグレーの点を重ねることで赤い境界線だけに見えるプロットになる。
+ geom_point(size=3, color="red") + geom_point(size=1.5, color="grey90")

ggplot関数に+していくとqplotより複雑なことができる(らしい)

ggplotで基本的なデータ要素、X、Yを決めてあげて、それに+してどんなプロットの形にするか等を追加していくことが可能みたい。 p <- ggplot(d, aes ( Season, Value ) )
p + geom_boxplot ( aes ( fill = Species )

ggplot2のqplotで参照するページ

ggplot2のqplot関数のまとめ - ぬいぐるみライフ(仮)
qplot. ggplot2 0.9.3.1

結果をテキストファイルに書き出し

sink(“results.txt”) と書くと、これ以降の出力をresults.txtに書き出してくれる。止めるときは、 sink()

他に参考にするページ

Google の R の書き方案内

2013年4月22日月曜日

Rで外れ値を計算する方法

Rでスミルノフ・グラブス検定を用いて外れ値を検出する方法のメモです。

調べたら今のところ以下の3つ。
同じデータを用いてそれぞれ計算してみました。

1. outliersパッケージのgrubbs.test関数

> install.packages('outliers')
> library(outliers)
> grubbs.test(df)
Grubbs test for one outlier
data:  df
G = 2.5060, U = 0.5194, p-value = 0.03119
alternative hypothesis: highest value 138.08 is an outlier

2014年1月9日追記
こちらの有り難いページによれば、typeという引数を設定することにより2つの外れ値を出すことも可能だそうです。
type=20 → 大小どちらか片側から最大2つまで外れ値を表示
type=11 → 大小両方から最大2つまでの外れ値を表示
type=10 → 大小どちらか片側から外れ値を1つ表示

2. 青木繁伸先生のSG関数

>SG(df)
[[1]]
スミルノフ・グラブス検定
data:  min(df) = 72.99
t = 1.275, df = 13, p-value = 1
[[2]]
スミルノフ・グラブス検定
data:  max(df) = 138.08
t = 2.506, df = 13, p-value = 0.03119
attr(,"class")
[1] "SG"
ここで有意水準を5%とすると、p < 0.05 の場合はその最大値または最小値が外れ値であると判断できます。リンク先の注意書きにもあるように外れ値は1個ずつ除外すべきですので、最大値または最小値を除外して再度SG関数で計算してみる必要があります。

3. 外れ値を自動的にループして除外してくれるfunction

R - 井上 潤 「外れ値の検出-1」にとても便利な関数がありました。感謝。
上の2つの方法だと、一度外れ値が見つかったらそれを自分で除外して、再度外れ値を検証しなくてはなりません。
しかし、この方法だと一個の外れ値を除外した後、自動的にループして新たに外れ値があるか検証してくれます。何度か繰り返して外れ値がすべて除外した後のデータは以下で取得できます。
  SG(x)$x

こちらも参考に。


2013年3月26日火曜日

R の ggplot2 で facet_wrap のスケールを変える

図を描きたくてRのggplot2パッケージを試しています。
その途中でちょっと躓いたので備忘録として書いておきます。

qplot関数において、facet_wrap もしくは facet_grid を足して格子状に分かれたプロットを描く際に、軸の範囲を設定する方法です。
スケールを設定しない場合は、例えば以下のような記述。

qplot(carat, price, data = diamonds) + facet_wrap (clarity~cut)

これを、以下のように書くとスケールを変えることができます。

1. 自動的にスケールを設定

qplot(carat, price, data = diamonds) + facet_wrap (clarity~cut, scales="free")
と書くと、各々のプロットに適したスケールが自動的に設定されます。
ちなみに scales の引数を free_y にしたらY軸のみ、free_x にしたらX軸のみ自動的に設定されます。

2. 任意の範囲でスケールを設定

qplot(carat, price, data = diamonds) + facet_wrap (clarity~cut) + coord_cartesian(xlim = c(0, 1), ylim = c(250,1000))
と書くと、自分の好きな範囲で軸を設定できます。
(2013/03/29追記)ためしてませんが、scale_x_continuousなどの書き方でも可能のようです。勉強必要。

この書き方だと全部の軸が一斉に変わってしまうのですが、個々のプロットに任意の値を設定することはできるんでしょうか…。まだまだ勉強が必要です。
とりあえず備忘録でした。