はだだだだ

定食にサラダは不要だと思う。

MENU

ggplotでgeom_lineをたくさん書く方法

シミュレーション結果をグラフに描くときに、geom_lineをたくさん書きたくなりました。工夫が必要なため、メモを残しておきます。

まず、以下のようなデータを想定します。

df <- tribble(
  ~x, ~y1, ~y2, ~y3, ~y4, ~y5,
   1,   1,   2,   3,   4,   5,
   2,   1,   2,   3,   4,   5,
   3,   1,   2,   3,   4,   5,
   4,   1,   2,   3,   4,   5,
   5,   1,   2,   3,   4,   5
)
>df
# A tibble: 5 x 6
      x    y1    y2    y3    y4    y5
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     1     1     2     3     4     5
2     2     1     2     3     4     5
3     3     1     2     3     4     5
4     4     1     2     3     4     5
5     5     1     2     3     4     5

やりたいことは以下のようなグラフを書くことです。

ggplot(data = df, aes(x = x)) +
  geom_line(aes(y = y1)) +
  geom_line(aes(y = y2)) +
  geom_line(aes(y = y3)) +
  geom_line(aes(y = y4)) +
  geom_line(aes(y = y5))

f:id:hadadada00:20190530045057p:plain

この場合はグラフが5本程度のため、直接geom_lineでつないでもそれほど冗長な感じはしませんが、これを100本書きたいとなるとそうはいきません。

方法として2パターン考えました。

geom_lineをfor文で大量生産する方法

以下のリンクの方法です。

r - Using geom_line in a for loop - Stack Overflow

geom_lineをfor文の中に書いて+でつなげます。このとき、aes_stringを使うことに注意が必要です。

lines <- ggplot(data = df, aes(x = x))
for (i in 1:nrow(df)) {
  lines <- lines + geom_line(aes_string(y = names(df)[i+1]))
}

後は以下で描画するだけです。追加でグラフや設定を足したい場合は+で続きを書けば大丈夫です。

lines +
  ggtitle("case1 : for loop")

f:id:hadadada00:20190530050241p:plain

gatherでデータの構造を変えてgroupでまとめる方法

ggplotの思想的にはこちらの方法が自然だと思います。

まず、データフレームの構造をgatherで変更します。

df2 <- df %>%
  gather(key = "key", value = "y", -x)

df2

>df2
# A tibble: 25 x 3
       x key       y
   <dbl> <chr> <dbl>
 1     1 y1        1
 2     2 y1        1
 3     3 y1        1
 4     4 y1        1
 5     5 y1        1
 6     1 y2        2
 7     2 y2        2
 8     3 y2        2
 9     4 y2        2
10     5 y2        2
# ... with 15 more rows

横長のデータが縦長になりました。これでaesの中でgroupが使えます。

ggplot(data = df, aes(x = x, y = y, group = key)) +
  geom_line() +
  ggtitle("case2 : gather")

f:id:hadadada00:20190530050833p:plain

以上