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))
この場合はグラフが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")
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")
以上