デンドログラムをヒートマップのまわりに描き足す

MikuHatsune2013-05-15

マイクロアレイをやるのにgplotsパッケージのheatmap.2関数を使っていたのだが、デフォルトで使うと正方形のプロットになって、行と列の数が極端に異なるときに気持ち悪い。
というわけでアイマスデータベースimas1.txtを使ってやってみよう。
同じクラスターになったものを色分けすることも追加する。

data0 <- read.delim("imas.txt", fileEncoding="utf-8")
CV <- data0$name
data1 <- as.matrix(data0[, -1])

library(gplots)
cols <- greenred(100)
rownames(data1) <- CV
h0 <- heatmap.2(data1, col=cols, scale="col", trace="none", dendrogram="both", key=TRUE)


heatmap.2でできたオブジェクトは、行と列についてのデンドログラム、補正した後のデータ、色付けの範囲などを含んでいるので、これらを取り出して、あとはちまちまプロットしていけばいい。

names(h0)
 [1] "rowInd"        "colInd"        "call"          "colMeans"      "colSDs"        "carpet"        "rowDendrogram" "colDendrogram" "breaks"        "col"           "colorTable"   
h1 <- h0$carpet[, colnames(data1)] # 列は並び替える
cuth0 <- cut(h0$colDendrogram, h=20) # 距離の遠さが同じ群を分割できる
nodes <- sapply(cuth0$lower, function(x) attributes(x)$member) # 群の中の要素の数を数える
cols0 <- rainbow(length(nodes))
layout(t(rbind(mapply(rep, 1:2, 48), 4:3))) # プロット領域を適当に設定する
par(mar = c(0.2, 4, 0.5, 0))
plot(h0$colDendrogram, horiz=FALSE, axes=FALSE, xaxs="i", leaflab="none", edgePar=list(col=1)) # デンドログラムを描く
cumnodes <- cumsum(nodes)
x0 <- cbind(head(c(1, cumnodes+1), -1), cumnodes)
for(i in seq(nrow(x0))) polygon(c(x0[i,], rev(x0[i,])) + c(-1, 1, 1, -1)*0.5, par()$usr[3] + rep(c(0, 3), each=2), col=cols0[i], border=NA) # 群
par(mar = c(10, 4, 0, 0))
image(seq(nrow(h1)), seq(ncol(h1)), h1, col=cols, xlab="", ylab="", axes=FALSE) # heatmapを描く
axis(1, at=seq(rownames(h1)), label=rownames(h1), tick=0, las=2, line=-0.8, cex.axis=1.2)
axis(2, at=seq(colnames(h1)), label=colnames(h1), tick=0, las=2, line=-0.8, cex.axis=1.5)
par(mar = c(10, 0.5, 0, 1))
panel <- t(as.matrix(unique(c(h0$colorTable$low, h0$colorTable$low))))
image(y=c(panel), z=panel, col=cols, axes=FALSE, ylab="") # カラースケールを描く
axis(4, las=2, tick=0, line=-0.8)

外れ値アイマスメンバー探しをやったときは、諸星きらり及川雫が外れ値として出てきたが、この2人は同じデブクラスタになった。
あとはすべてのプロフィールが平均以下のロリクラスタ(佐城雪美、市原仁奈、横山千佳etc)、プロフィールはいたって平均的な平凡クラスタ(渋谷凛天海春香)などに分類できる。