ggplot2 の基本型

ggplot2 の基本的な書式は、下記のようになっています。

ggplot() + geom_xxx() + スケール + コーディネイト + テーマ + ラベル

最初の ggplot() 関数では、使用するデータを含むオブジェクトと、オブジェクトのうち、実際使用するデータをaes()で宣言します。次の geom_xxx() 関数で、ヒストグラムや、散布図、ヒートマップといった表示形式を宣言します。 geom_bar(), geom_point(), geom_tile() などがあります。ここまでが、グラフの描画に最低限必要なオブジェクトです。

ある値に応じて、プロットの色やサイズを変更する場合は、スケールの部分で指定します。scale_fill_gradient() 関数や、scale_size() 関数があります。

コーディネイトの部分は、必須ではありませんが、描画する範囲 (従来の xlim, ylim に近い) を指定する場合に用います。coord_cartesian() 関数や、プロットの向きを回転させる coord_flip() 関数などがあります。

テーマの部分で、見た目の変更を行います。プロットの背景や、各軸の目盛りの書式などがまとめて定義されたテーマを指定できます。モノクロのテーマ (theme_bw), 明るいテーマ(theme_light), 従来のスタイル (theme_classic), 背景なし (theme_void) などがあります。

ラベルの部分で、x軸のラベル、y軸のラベル、タイトル、キャプションなどを指定します。labs( x = "x軸ラベル", y = "y軸ラベル", title ="タイトル")

全て指定すると、下記のようなコードになります。(1行に書く必要はありません。途中で、改行を入れることができます。)

input_data <- tibble("Sample1" = rnorm(100))

ggplot(input_data, aes(Sample1)) +
  geom_histogram(bins = 20, aes(fill = ..x..)) +
  scale_fill_distiller(palette = "Blues") +
  coord_cartesian(xlim = c(-2, 2)) +
  theme_light() +
  labs(title = "histogram", y = "read count")
設定を変更したヒストグラムの例

オブジェクトの保存

途中のコードをオブジェクトとして保存することもできます。確定している部分をオブジェクトにすることで、テーマだけ変更して確認したりといった、コードの再利用もしやすくなります。

オブジェクトに格納した段階では、グラフの描画は行われません。オブジェクトをコールした時点(=オブジェクトに代入しなかった場合)で描画されます。

g  <- ggplot(input_data, aes(Sample1))                 # g に格納。
gg <- g + geom_histogram(bins = 20, aes(fill = ..x..)) # gg に格納。

# グラフは、下記でコールされた時点で描画される。
gg + scale_fill_distiller(palette = "Blues") +
  coord_cartesian(xlim = c(-2, 2)) +
  theme_light() +
  labs(title = "histogram", y = "read count")
 

ggplot2 を使った作図方法

tidyverse では、 ggplot() 関数を用いて図を作成します。従来の plot 関数と異なり、多次元のデータも、2次元に並び替える必要があるため、多少、慣れが必要です。

まずは、1次元のデータを例に、ggplot の作法を紹介します。(この場合は、並び替える必要はありません。)

> # 適当なデータを100個生成
> input_data <- tibble("Sample1" = rnorm(100))
> 
> input_data
# A tibble: 100 x 1
   Sample1
     <dbl>
 1 -1.64
 2  1.91
 3  0.890
 4  0.178
 5  0.0393
 6 -1.09
 7  0.544
 8  0.387
 9 -2.48
10 -0.309
# … with 90 more rows
>
>
> ggplot(input_data, aes(Sample1)) + geom_histogram(bins = 20)

ggplot() 関数で、どのオブジェクトのどの列を使うかを指定します。その際、列のデータは、aes() の形式で指定します。上記では、count の列を指定しています。

ggplot の後の 「+」 に続く関数で、図の種類を指定します。上記では、 geom_histogram() として、ヒストグラムを指定しています。(bins = 20 は、ヒストグラムの細かさを指定するオプション。)

ウィンドウが開き、下記のような画像が表示されます。

ヒストグラムの例

画像を保存するには、 ggsave() 関数を用います。ファイルの形式は、拡張子 (.png, .pdfなど) から、自動で判断されます。(従来コードのように、いちいちデバイスを指定しなくて済むので楽です。)

ggsave("ファイル名.png")

> ggsave("histogram_image.png")
Saving 7 x 7 in image

オプションなしで、 ggsave 関数を使用すると、その時点で表示されているウィンドウの大きさで画像ファイルが作成されます。上記の場合は、7 インチ x 7 インチのサイズで保存されています。明示的に、サイズを指定する場合は、次のように width, height, unit オプションで指定します。

> ggsave("histogram_image.png", width = 7, height = 7, unit = "in")

その他の1次元データを表示する関数は、 geom_dotplot(), geom_density(), geom_bar() などがあります。 チートシートでは、 one variable の項目で紹介されています。

ggplot2

https://ggplot2.tidyverse.org

 

列名の変更: rename()

列名を変更するには、 rename() 関数が使えます。書式は、 rename("新しい列名" = 既存の列名) です。

下記の例では、 Sample1 を S1 にリネームしています。

> input_data
# A tibble: 3 x 3
  Id    Sample1 Sample2
  <chr>   <dbl>   <dbl>
1 id1         1       4
2 id2         2       5
3 id3         3       6
>
>
> input_data %>% rename("S1" = Sample1)
# A tibble: 3 x 3
  Id       S1 Sample2
  <chr> <dbl>   <dbl>
1 id1       1       4
2 id2       2       5
3 id3       3       6

従来のデータフレームのように colnames() を使うこともできます。変更する列が多い場合は、こちらの方が便利かもしれません。元のオブジェクトを上書きしてしまうため、注意が必要です。

> colnames(input_data) <- c("Id", "S1", "S2")
> input_data
# A tibble: 3 x 3
  Id       S1    S2
  <chr> <dbl> <dbl>
1 id1       1     4
2 id2       2     5
3 id3       3     6

str_replace と組み合わせることもできます。例では、S を Sample に置換しています。

> colnames(input_data)
[1] "Id" "S1" "S2"
>
> colnames(input_data) <- colnames(input_data) %>%
 str_replace("S", "Sample")
>
> input_data
# A tibble: 3 x 3
  Id    Sample1 Sample2
  <chr>   <dbl>   <dbl>
1 id1         1       4
2 id2         2       5
3 id3         3       6
 

データフレームから tibble に変換: as_tibble, rownames_to_column

データは、tibble 形式だけで統一できるとスッキリしますが、まだまだ、古いパッケージを利用することも多いと思います。その場合、結果のオブジェクトがデータフレーム形式であることも多いでしょう。

> input_df <- read.delim("input_data.tsv", row.names = 1)
>
> # data.frame 形式のテーブル
> input_df
    Sample1 Sample2
id1       1       4
id2       2       5
id3       3       6

下記のように as_tibble() 関数で、データフレームから tibble に変換できます。tibble は、rownames を持たないため、データフレームの rownames を普通の列 (column) に変換しておく必要があります。その名の通りの関数 rownames_to_column() も準備されています。

> as_tibble(rownames_to_column(input_df, "Id"))
# A tibble: 3 x 3
  Id    Sample1 Sample2
  <chr>   <int>   <int>
1 id1         1       4
2 id2         2       5
3 id3         3       6

複雑なオブジェクトの場合は、rownames_to_column() の前に、as.data.frame() などとしておきます。

> as_tibble(rownames_to_column(as.data.frame(input_df), "Id"))
# A tibble: 3 x 3
  Id    Sample1 Sample2
  <chr>   <int>   <int>
1 id1         1       4
2 id2         2       5
3 id3         3       6

tibble からデータフレームに変換 #

逆に、tibble からデータフレームにする必要があれば、 column_to_rownames() 関数を使います。引数で、どの列を rownames にするか指定します。

> input_data
# A tibble: 3 x 3
  Id    Sample1 Sample2
  <chr>   <dbl>   <dbl>
1 id1         1       4
2 id2         2       5
3 id3         3       6
>
>
> column_to_rownames(input_data, "Id")
    Sample1 Sample2
id1       1       4
id2       2       5
id3       3       6
 

R (tidyverse) ワードカウント: group_by(), summarize()

tidyverse では、ワードカウントも、group_by() 関数に続いて、 summarize() 関数を使うと、簡単に記述できます。

下記のように複数の Symbol がある時、AAA は3個、CCC は2個と数えるようなケースです。

> meta_data %>% select(Id, Symbol)
# A tibble: 9 x 2
  Id    Symbol
  <chr> <chr>
1 id1   AAA
2 id2   AAA
3 id3   AAA
4 id4   BBB
5 id5   BBB
6 id6   BBB
7 id7   CCC
8 id8   CCC
9 id9   DDD

カウントするために、いったん、 mutate(count = 1) として、計算用のデータを格納しておきます。

> meta_data %>% select(Id, Symbol) %>% mutate("count" = 1)

# A tibble: 9 x 3
  Id    Symbol count
  <chr> <chr>  <dbl>
1 id1   AAA        1
2 id2   AAA        1
3 id3   AAA        1
4 id4   BBB        1
5 id5   BBB        1
6 id6   BBB        1
7 id7   CCC        1
8 id8   CCC        1
9 id9   DDD        1

group_by(Symbol) %>% summarize("total" = sum(count)) として、カウントの合計を求めることができます。続けて書くと、下記のようなコードになります。

result_data <- meta_data %>%
  select(Id, Symbol)     %>%
  mutate("count" = 1)    %>%
  group_by(Symbol)       %>%
  summarize(total = sum(count))
>
>
> result_data
# A tibble: 4 x 2
  Symbol total
  <chr>  <dbl>
1 AAA        3
2 BBB        3
3 CCC        2
4 DDD        1

ちなみに、 summarize("total" = sum(Symbol)) とすることはできません。sum() 関数が integer や double などの数値を引数とすることに対して、Symbol は character であり、型が異なるためです。