Lattice and ggplot graphics, side by side 実践3 描図オプションの仕組み

  • 今回、使用するデータは4変数72サンプルのデータフレーム
library(lattice)
library(ggplot2)
data(Oats, package = "MEMSS")
> str(Oats)
'data.frame':   72 obs. of  4 variables:
 $ Block  : Factor w/ 6 levels "I","II","III",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Variety: Factor w/ 3 levels "Golden Rain",..: 3 3 3 3 1 1 1 1 2 2 ...
 $ nitro  : num  0 0.2 0.4 0.6 0 0.2 0.4 0.6 0 0.2 ...
 $ yield  : num  111 130 157 174 117 114 161 141 105 140 ...
dev.off()
# yieldをy軸に、nitroをx軸にしてxyプロットする。VarietyとBlockとの2つのファクタで場合分けしてプロットする。プロットの点・線のタイプは "o"
tp1.oats <- xyplot(yield ~ nitro | Variety + Block, data = Oats, type = "o")
print(tp1.oats)
dev.new()
# nitryoをx軸に、yieldをy軸にしてプロットせよ。線を引け。点を描け。BlockとVarietyとの2つのファクタで場合分けしてプロットせよ、そのとき列を3とせよ
pg.oats <- ggplot(Oats, aes(nitro, yield)) + geom_line() + geom_point() + facet_wrap(~Block + Variety, ncol = 3)
print(pg.oats)

    • latticeが左下から上へと描くのに対して、ggplot2が左上から下へと描く、という違いは前の記事と同じ
  • 一度できた、描図情報を持ったオブジェクトのうち、一部を取り出してみる
dev.off()
# latticeの場合
# 4行3列で描かれているが、格納状態は3行4列(らしい)
# その上で、格納状態として第1行を取り出すと
# 4x3=12の図のうち、再下段の3つの図のみが取り出される
print(tp1.oats[, 1])
dev.new()
# ggplot2の場合
# 行列的な扱いはできない(らしい)
# その代わり、subset()関数をリストであるpg.oatsに作用させて、該当するもののみを抜き出している
# ggplot2では"+"演算で制御するので、それをリスト(や行列)に一括処理する演算子"%+%"も使える(ということらしい)
# ggplot2では、4x3=12の図のうち最上段の3つが取り出されている
pg <- pg.oats %+% subset(Oats, Block == "I")
print(pg)
help(subset)

  • 複数のグラフの隙間を埋めて描く
dev.off()
# aspectというオプションで埋めている
pl <- update(tp1.oats, aspect = "xy")
print(pl)
dev.new()
# unit()関数のためにgridパッケージを読み込む
library(grid)
# パネルのマージン幅をなくしている
pg <- pg.oats + opts(panel.margin = unit(0, "lines"))
print(pg)

    • 幅の調整に関してlatticeとggplot2とで完全一致させられていない
  • 複数のグラフの配置変えとか、スペースの入れ方の細かい指定などについての例が出ているが、はっきり言って、興味がないので、飛ばします
  • 視点を変えてプロット
# barleyというデータを使う
> str(barley)
'data.frame':   120 obs. of  4 variables:
 $ yield  : num  27 48.9 27.4 39.9 33 ...
 $ variety: Factor w/ 10 levels "Svansota","No. 462",..: 3 3 3 3 3 3 7 7 7 7 ...
 $ year   : Factor w/ 2 levels "1932","1931": 2 2 2 2 2 2 2 2 2 2 ...
 $ site   : Factor w/ 6 levels "Grand Rapids",..: 3 6 4 5 1 2 3 6 4 5 ...
dev.off()
# x軸にyield、y軸にvariety、それをsiteごとのグラフとする
# yearでグループに分けて(色分けして)プロット
# aspectで縦横の比を調整している
# layoutで並べ方を決めている
pl <- dotplot(variety ~ yield | site, barley, layout = c(1, 6), aspect = c(0.7), groups = year, auto.key = list(space = "right"))
print(pl)
dev.new()
# barleyを使って yieldをx軸、varietyをy軸に描け、yearを使って色分けせよ
# 点を描け
# site でまとめて描き、1列に並べよ
pg <- ggplot(barley, aes(yield, variety, colour = year)) + geom_point() + facet_wrap(~site, ncol = 1)
print(pg)

  • 点の形を指定したり、線の色を指定したり
dev.off()
# 点の形を指定
key.variety <- list(space = "right", text = list(levels(Oats$Variety)), points = list(pch = 1:3, col = "black"))
# Oatsデータを使って、x軸にnitro、y軸にyieldで描け。Block別に描け。Varietyに関してグループ分けして(点の形を変えて)描け。線はdarkgrey、点はblack
# x,y軸ラベルを指定。メインタイトルは上に、サブタイトルは下に
pl <- xyplot(yield ~ nitro | Block, Oats, aspect = "xy", type = "o", groups = Variety, key = key.variety, lty = 1, pch = 1:3, col.line = "darkgrey", col.symbol = "black", xlab = "Nitrogen concentration (cwt/acre)", ylab = "Yield (bushels/acre)", main = "Yield of three varieties of oats", sub = "A 3 x 4 split plot experiment with 6 blocks")
print(pl)
dev.new()
# pにggplot()の出力をとりあえず格納(わかりにくくなるから)
# nitroをx軸、yieldをy軸に。Varietyでグループ分けして描き、点の形もVarietyで決める
p <- ggplot(Oats, aes(nitro, yield, group = Variety, shape = Variety))
# 線をdarkgreyで引き、点を打つ(色はデフォルト~black)
# Blockごとにまとめる
# タイトルは改行コードを使ってlatticeの表示に近くしている
pg <- p + geom_line(colour = "darkgrey") + geom_point() + facet_grid(~Block) + scale_x_continuous(breaks = seq(0, 0.6, by = 0.2), labels = seq(0, 0.6, by = 0.2)) + opts(title = "Yield of three varieties of oats") + labs(x = "Nitrogen concentration (cwt/acre) \n A 3 x 4 split plot experiment with 6 blocks", y = "Yield (bushels/acre)")
print(pg)

  • Bar chart
    • Titanicをデータとする
> str(Titanic)
 table [1:4, 1:2, 1:2, 1:2] 0 0 35 0 0 0 17 0 118 154 ...
 - attr(*, "dimnames")=List of 4
  ..$ Class   : chr [1:4] "1st" "2nd" "3rd" "Crew"
  ..$ Sex     : chr [1:2] "Male" "Female"
  ..$ Age     : chr [1:2] "Child" "Adult"
  ..$ Survived: chr [1:2] "No" "Yes"
# Titanicのデータとして、Freqをx軸、Classをy軸とする
# SexとAgeの組合せカテゴリ(4つ)別に描き
# Survivedで色分けする
dev.off()
pl <- barchart(Class ~ Freq | Sex + Age, data = as.data.frame(Titanic), groups = Survived, stack = TRUE, layout = c(4, 1), auto.key = list(title = "Survived", columns = 2))
print(pl)

dev.new()
# Titanicをデータとし、Classをx軸、Freqをy軸にして
# fill:色塗りをSurvivedでする…か?
# barはあくまでも、「Classを底辺に、Freqを高さ」にするので、ggplot()関数にはこの順で与え、その上で、縦横を変換する必要がある
p <- ggplot(as.data.frame(Titanic), aes(Class, Freq, fill = Survived))
# stat(statistical transformation)を"identity"(変えずに、素の値)にして、AgeとSexとの組合せカテゴリで場合分けをし、1行で表示する
# coord_flip()でx,y軸を変換する
pg.titanic <- p + geom_bar(stat = "identity") + facet_wrap(~Age + Sex, nrow = 1) + coord_flip()
print(pg.titanic)

    • barの長さを相対長に変える
dev.off()
# scalesパラメタでx軸(Freq)に関して"free"にしてある
pl <- barchart(Class ~ Freq | Sex + Age, data = as.data.frame(Titanic), groups = Survived, stack = TRUE, layout = c(4, 1), auto.key = list(title = "Survived", columns = 2), scales = list(x = "free"))
print(pl)

dev.new()
# scalesを"free"に指定
pg <- pg.titanic + facet_wrap(~Age + Sex, nrow = 1, scales = "free") 
print(pg)