ggplot2でグラフ書きはじめた話

グラフを生成するために、numbersを普段使っていたけれどもデータ量が多くなってきてだるくなってきたので、もっと楽に生成したくなったのでRのggplot2というのを使うこととした。
あと、numbersから作ったグラフだけを書きだす方法が分からないし、psファイルとかで書きだす方法もなかったのもある。ggplot2ならだいたいの形式は書き出せると思う。

ちなみに統計の話とかは知らない。とにかくグラフを沢山簡単に作りたいというモチベーション。

Rの操作の話

まず、Rが分からないので
はじめてのS‐PLUS/R言語プログラミング―例題で学ぶS‐PLUS/R言語の基本 - soh335 memo
を読んだ。 普段使う言語と違って関数言語かつベクトル的な操作が基本になっているので、ぱっと読むだけでも感じがつかまないと、グラフのデータの生成の為の操作とかに手こずる。

でも、Rの操作に不安があったので基本的なcsvのデータをperlで生成した。

csv <- read.csv(path)

みたいな感じでcsvを読み込む。ちょっと詰まったのが複数な操作で普通はforで書くけど

csvs <- lapply(Sys.glob("/path/to/*/*.csv"), read.table)

みたいな感じで書く方がすっきりする。

ちなみにperlで吐き出したcsvがファイル名とかディレクトリ名に情報が入っていて上のようにマージすると意味が分からなくなるので

get_csv <- function(path) {
  tmp <- read.csv(path)
  hoge <- unlist(strsplit(path, "/"))[5]
  csv = data.frame(
    tmp,
    data.frame(
      hoge=rep(hoge, nrow(tmp))
    )
  )
}

みたいな感じとかでやった。ちなみにhogeが数字の時は、as.numeric した。

次からグラフ書く話

install.packages(ggplot2)

とやるとインストール出来るけど、今回はgithubはにあるdev版を使いたいので

# install.packages("devtools")
library(devtools)
install_github("ggplot2")

として

library(ggplot2)

として読み込む。

グラフィックスのためのRプログラミング―ggplot2入門

グラフィックスのためのRプログラミング―ggplot2入門

グラフィックスのためのRプログラミング―ggplot2入門


を見ながらやる。網羅的で何が出来るかわかりやすい。

まずcsvのデータからフィルタリングする時

fill_csv <- subset( csv, csv$key == "hoge" )
fill_csv <- subset( csv, csv$key %in% c("hoge", "fuga" ) )
fill_csv <- subset( csv, csv$key == "hoge" & csv$type == 1 )

みたいな感じでやる。まず基本的なグラフを書く。
ggplot2を読み込むとdiamondsというデータが読み込まれてる

heahd(diamonds)

carat cut color clarity depth table price x y z
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
4 0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48

headってやるとデータを少し見る事が出来る。

qplot(carat, price, data = diamonds, geom = "point" )

f:id:soh335:20111218151621p:image

みたいな感じになる。pointの場合は第一引数がx軸、第二引数がy軸。

qplot(carat, price, data = diamonds, geom = "point", color = color)

f:id:soh335:20111218151622p:image

で色がつく。よく分からないけど、subsetした時にcolor = factor(color) するようにしないとsubsetする前のものが凡例に出てきてしまう。

qplot(carat, price, data = diamonds, geom = "point", color = color) + geom_smooth()

で、平滑化線が色事に出せる。作ったグラフに別のグラフを足す事も出来る。

f:id:soh335:20111218151623p:image

今回はする必要ないが、x軸とかy軸のパラメータとかをいじるにはscaleっていうのを設定する

qplot(carat, price, data = diamonds, geom = "point", color = color) + geom_smooth() + scale_y_log10()

f:id:soh335:20111218151624p:image

qplot(carat, price, data = diamonds, geom = "point", color = color) + geom_smooth() + facet_grid( color ~ . )

facet_gridで色事にグラフを分けて並べる事も出来る。

f:id:soh335:20111218151625p:image

分かりやすい。

qplot(carat, price, data = diamonds, geom = "point", color = color, alpha = I(1/50)) + geom_smooth() + facet_grid( color ~ . )

alphaを下げる事でどこに集中してるのかが見やすくなった。Iで囲まないと凡例が複数になってしまう。

f:id:soh335:20111218151626p:image

qplot(carat, price, data = diamonds, geom = "point", color = color, alpha = I(1/50)) + geom_smooth() + facet_grid( color ~ . ) + opts(legend.position= "bottom", legend.direction = "horizontal")

で、凡例の位置を変えられる。

f:id:soh335:20111218151627p:image

devのggplot2にはguideというのが加わっていてこれを使うと凡例周りを操作しやすくなっている。
例えば、ラベルを複数行にしたいとかは、今までの方法だと分からなかったけどこれなら

qplot(carat, price, data = diamonds, geom = "point", color = color, alpha = I(1/50)) + geom_smooth() + facet_grid( color ~ . ) + opts(legend.position= "bottom", legend.direction = "horizontal") + guides( color = guide_legend( title.position="top", title.hjust=0.5, ncol=4) )

f:id:soh335:20111218151628p:image

という感じで出来る。便利。scale_***みたいな関数にもguideというのが渡せるので先にguide_legendで凡例の位置とかを決めておいて

scale_linetype_manual( guide=g, values=c(...)) 

みたいな感じも出来る。詳しくはhelp(guides)

vim

これいちいち打ってるとめんどくさいのでvimで操作したい。
quickrunが対応してるので簡単に実行出来るが、グラフが出る前に終了してしまうので適当にpngとかで保存して開く関数を書いた。

ggopen <- function(graph, path, ...) {
  ggsave(path, plot = graph, ...)
  system(paste("open", path, sep=" "))
}

まぁあとrefとかneocomplcacheと連携出来るように時間できたらしたいとこ。関数を探すのがめんどくさい。

まとめ

本当に色々カスタマイズできて今回はpointしか載せてないが沢山ある。
プログラマブルなので例えばpointのsizeを置かれる位置の高さによって変えるとか、線の種類を変えるとかも簡単に出来る。
結論、楽しい。