昨日のTokyoRの一次会でちょっと話したやつ
View()
で見ていくとき、layersに入っているレイヤーオブジェクトには名前がなく、[[1]]
とか[[2]]
とかそっけない。そして複数のレイヤーを重ねた場合にはどれがどれかわからん…!となりそう。
じゃあレイヤーに名前つけてみるかぁという気持ちをRで書くとこんな感じかな。
# データの準備。これは例のkazutanさんの記事からの引用。 library(ggplot2) g_null <- ggplot() geom_point_iris <- geom_point(data = iris, mapping = aes(x = Sepal.Length, y = Sepal.Width), stat = "identity", position = "identity") g_gpoint_iris <- g_null + geom_point_iris # 準備はここまで # 名前を付けるのはここ。レイヤー枚数に応じて代入する文字を適当に追加してあげてください。 names(g_gpoint_iris$layers)<-c("Scatter_Plot") View(g_gpoint_iris)
これでgeom_point()
で追加されたlayerは"Scatter_Plot"1という名前を持ちます。コンソール上にg_gpoint_iris
と書けばちゃんとプロットもされますね。
おまけ
まぁこれだけで終わるのもなんなので、zeallotを使ってlayer取り出そうと思ってやってみたコードがこちらです。
library(ggplot2) library(zeallot) library(magrittr) # %->% の list 対応 destructure.list <- function(x){x} # 以下はggplot側のデータの作成(さっきのと同じ) g_null <- ggplot() geom_point_iris <- geom_point(data = iris, mapping = aes(x = Sepal.Length, y = Sepal.Width), stat = "identity", position = "identity") g_gpoint_iris <- g_null + geom_point_iris # View(g_gpoint_iris) # classをいったん消してlistにするので復元するためにclassの値を保存しておく class_name <- class(g_gpoint_iris) # 同様に、要素の名前も保存しておく top_hier_names <- names(g_gpoint_iris) # これを実行すると.GlobalEnvに9つの変数が出てくる… g_gpoint_iris %>% unclass %->% c(data, layers, scales, mapping, theme, coordinates, facet, plot_env, labels) # layerに名前を付ける。今回は1つだけ names(layers)<-c("Scatter_Plot") # listを再構成 g_gpoint_iris_ln<-list(data, layers, scales, mapping, theme, coordinates, facet, plot_env, labels) # classを復元 class(g_gpoint_iris_ln) <- class_name # nameも復元 names(g_gpoint_iris_ln) <- top_hier_names # みてみる View(g_gpoint_iris_ln)
と、いう感じ。ちゃんとg_gpoint_iris_ln
とコンソールに書いてEnterでplotされますな。
補足
道を踏み外した感じがありますが、ちょっと色々確認したかったので…。
destructure.list <- function(x){x}
はコメントにあるように %->%
の list 対応。
zeallot
で%->%
を使う場合にはclassに応じた関数を準備しておく必要がある。data.frameは内部でlistにしているだけなので、listなら引数をそのまま返せば良いだろう。
しかし、なぜ素の状態でlistの対応がないのだろう。不思議
実はdestructure.gg
だとなんだかうまくいかないのですよね…(理由はよくわかっていない)。そのため、gg
のオブジェクトはそのまま渡せず、今回はunclass()
でclass属性を消して単なるlistとなっています。で、これをzeallot
で分解して各要素に分けています。
その後layersに名前を与え、分解した要素をlistにして再構成して、class()
でもともと持っていた"gg"と"ggplot"を与え、listsの要素には元のgg
クラスだった時の名前を与えなおしています。ggplot
のオブジェクトは要素名が上記のようになっていないとプロットしてくれないらしく。namesを与える部分を省略して実行してみてください。View()
で中身を見ても良いかも。
これはRStudio上の挙動なのかもしれませんが…。素のRで確認とかはしていないです。
そもそもなぜgg
のオブジェクトをコンソール上で叩くとプロットされるのかと言えば、実際にはggplot2:::print.ggplot(g_gpoint_iris)
が呼び出されているからで2…しかしこれはREPL上の動きなので実際は…
yutannihilationさんの記事をご参照ください
notchained.hatenablog.com
zeallot
を積極的に使っていきたみだけでやってみた感じの記事ですね。
Enjoy!!