web-dev-qa-db-ja.com

ggplot2でヒートマップを作成する方法は?

Ggplot2を使用してヒートマップを作成しようとしています。 この例 を見つけました。これは基本的にデータを使用して複製しようとしていますが、問題が発生しています。私のデータは次のような単純な.csvファイルです。

people,Apple,orange,Peach
mike,1,0,6
sue,0,0,1
bill,3,3,1
ted,1,1,0

果物の名前がx軸に、人がy軸にある簡単なヒートマップを作成したいと思います。グラフは、各正方形の色が消費された果物の数を表す正方形を表す必要があります。 mike:Peachに対応する正方形が最も暗くなります。

ヒートマップの作成に使用しているコードは次のとおりです。

data <- read.csv("/Users/bunsen/Desktop/fruit.txt", head=TRUE, sep=",")
fruit <- c(Apple,orange,Peach)
people <- data[,1]
(p <- ggplot(data, aes(fruit, people)) + geom_tile(aes(fill = rescale), colour = "white") +    scale_fill_gradient(low = "white", high = "steelblue"))

このデータをプロットすると、x軸に果物の数、y軸に人の数が表示されます。また、果物の数を表す色のグラデーションも取得しません。ヒートマップとして表示されている人が食べた果物の数をx軸に表示して、果物の名前を取得するにはどうすればよいですか? Rで取得している現在の出力は次のようになります。

enter image description here

15
drbunsen

正直に言うと、@ dr.bunsen-上記の例は再現性が低く、チュートリアルの最初の部分を読んでいませんでした リンク 。これがおそらくあなたが探しているものです:

 library(reshape)
 library(ggplot2)
 library(scales)

 data <- structure(list(people = structure(c(2L, 3L, 1L, 4L), 
                                           .Label = c("bill", "mike", "sue", "ted"), 
                                           class = "factor"), 
                        Apple = c(1L, 0L, 3L, 1L), 
                        orange = c(0L, 0L, 3L, 1L), 
                        Peach = c(6L, 1L, 1L, 0L)), 
                    .Names = c("people", "Apple", "orange", "Peach"),
                    class = "data.frame", 
                    row.names = c(NA, -4L))
 data.m <- melt(data)
 data.m <- ddply(data.m, .(variable), transform, rescale = rescale(value))
 p <- ggplot(data.m, aes(variable, people)) + 
         geom_tile(aes(fill = rescale), colour = "white") 
 p + scale_fill_gradient(low = "white", high = "steelblue")

enter image description here

32
Geek On Acid

7(!)年後、データを正しくフォーマットする最良の方法は、tidyrではなくreshapeを使用することです。

gathertidyrを使用すると、データを再フォーマットして、予想される3つの列(y軸にperson、x軸にfruit、値にcount)を取得するのは非常に簡単です。

_library("dplyr")
library("tidyr")

hm <- readr::read_csv("people,Apple,orange,Peach
mike,1,0,6
sue,0,0,1
bill,3,3,1
ted,1,1,0")

hm <- hm %>%
  gather(fruit, count, Apple:Peach)
  #syntax: key column (to create), value column (to create), columns to gather (will become (key, value) pairs)
_

データは次のようになります。

_# A tibble: 12 x 3
   people fruit  count
   <chr>  <chr>  <dbl>
 1 mike   Apple      1
 2 sue    Apple      0
 3 bill   Apple      3
 4 ted    Apple      1
 5 mike   orange     0
 6 sue    orange     0
 7 bill   orange     3
 8 ted    orange     1
 9 mike   Peach      6
10 sue    Peach      1
11 bill   Peach      1
12 ted    Peach      0
_

完璧!プロットを始めましょう。 ggplot2でヒートマップを実行するための基本的なgeomは_geom_tile_であり、これに美的なxy、およびfillを提供します。

_library("ggplot2")
ggplot(hm, aes(x=x, y=y, fill=value)) + geom_tile() 
_

first attempt

悪くはありませんが、もっとうまくやることができます。

  • ヒートマップの場合、灰色の背景を取り除く白黒のテーマtheme_bw()が好きです。
  • また、RColorBrewerのパレットを使用するのも好きです(_direction = 1_を使用すると、値が大きいほど暗い色になり、それ以外の場合は-1になります)。利用可能なパレットはたくさんあります:赤、青、スペクトル、RdYlBu(赤-黄-青)、RdBu(赤-青)など。以下では「緑」を使用します。 RColorBrewer::display.brewer.all()を実行して、パレットがどのように見えるかを確認します。

  • タイルを正方形にしたい場合は、coord_equal()を使用するだけです。

  • 凡例は役に立たないことがよくありますが、特定のユースケースによって異なります。 guides(fill=F)を使用してfill凡例を非表示にできます。

  • _geom_text_(または_geom_label_)を使用して、タイルの上に値を印刷できます。美学xy、およびlabelが必要ですが、この場合、xyは継承されます。美学として_size=count_を渡すことで、より高い値を大きく印刷することもできます。その場合は、_size=F_をguidesに渡して、サイズの凡例を非表示にすることもできます。

  • colorを_geom_tile_に渡すことで、タイルの周りに線を引くことができます。

すべてを一緒に入れて:

_ggplot(hm, aes(x=fruit, y=people, fill=count)) +
  # tile with black contour
  geom_tile(color="black") + 
  # B&W theme, no grey background
  theme_bw() + 
  # square tiles
  coord_equal() + 
  # Green color theme for `fill`
  scale_fill_distiller(palette="Greens", direction=1) + 
  # printing values in black
  geom_text(aes(label=count), color="black") +
  # removing legend for `fill` since we're already printing values
  guides(fill=F) +
  # since there is no legend, adding a title
  labs(title = "Count of fruits per person")
_

Final heatmap

何かを削除するには、対応する行を削除するだけです。

1
asac