niszetの日記

アナログCMOS系雑用エンジニアが頑張る備忘録系日記

(R) x軸共通の場合に、列名が条件に合致した場合に全部y軸にプロットする (メモ)

簡単だけど、そのものずばりが見つけられなかったので。

とりあえずirisで。x軸は適当にindexを振っておいて、これを共通の軸とする。y軸方向にはSpecies(とid)を除いた全部をプロットしたいので、列名に"."が含まれているものを取り出してプロットする感じで。

とりあえず捻りのないやり方で…。

library(ggplot2)
library(magrittr)
library(dplyr)

# id振っておく
iris_ <- iris %>% mutate(id=row_number()) 

# 下地を作っておく
g <- ggplot(iris_, aes(x=id))

# 列名に条件を設けて取り出す。
coliris <- iris %>% select(contains(".")) %>% colnames()

# for文でまわす
for(i in coliris){
  g <- g + geom_point(aes_(y=as.symbol(i), color=as.factor(i)))
}
g <- g + ylab("Value") + scale_color_discrete(name="column")
# ggplot2:::print.ggplotでplotする。何か設定を追加するならこの前に。
g

これで、

f:id:niszet:20180327234150p:plain

こんな感じ。個人的には使う機会が多くなりそうなのでメモ。

この書き方で、色はちゃんと別々になるんだなぁ…

追記

コメントとTwitterのそれぞれで、あ~る・芸人一郎さんとAtsushiさんによりスマートな書き方を教えていただいたのでご紹介。

あ~る・芸人一郎さんのコードは、

require(tidyverse)
iris %>% 
dplyr::select(dplyr::contains(".")) %>% 
tibble::rowid_to_column("id") %>% 
tidyr::gather(key = key, value = value, -id) %>% 
ggplot2::ggplot(ggplot2::aes(x = id, y = value, colour = key)) +
ggplot2::geom_point()

Atsushiさんのコードは

library(dplyr)
library(tidyr)
library(ggplot2)
ggplot(
  iris[-5] %>%
    mutate(id = row_number()) %>%
    gather(column, Value, -id),
  aes(x = id, y = Value, color = column)
) +
  geom_point()

です。gatherを使えばaesでいけるんですね~。あ~る・芸人一郎さんのコードではtibble::rowid_to_column()でid列を追加していて、こういう便利関数は色々あるはずなのだけど全然追い切れていない…。
Atsushiさんのコードのように、ggplot()の関数の呼び出しの引数内でも %>% が使えます(最終的に評価されたものがggplotに渡る)

近いうちにgather()使いこなしのための記事を書かないといけませんね…!

あ~る・芸人一郎さん、Atsushiさん、ありがとうございました。

(他にもあるぞ!という方、まだまだ募集中…!)

追記の追記

Atsushiさんから、私のfor文を使っているコードのapply版もいただきました。やっぱりapply系の関数に置き換えるとスッキリしますね。
最近無理にapply使おうとして時間を無限に溶かしたので苦手意識が再燃…。こちらも頑張るぞい💪

# id振っておく
iris_ <- iris %>% mutate(id=row_number())

# 列名に条件を設けて取り出す。
coliris <- iris %>% select(contains(".")) %>% colnames()

ggplot(iris_, aes(x=id)) + 
  lapply( #レイヤーのリストが返る
    coliris, 
    function(i) 
      geom_point(
        aes_(y=as.symbol(i), color=as.factor(i))
      )
  ) +
  ylab("Value") + 
  scale_color_discrete(name="column")

Enjoy!!