まさかの3回目。
これらの記事の続きです。
先日の2回目の記事によって、無事にhistの表示のさせ方を変えることが出来たのですが、ここでteramonagiさんから
@niszet0
— 職業、イケメン。Nagi Teramo (@teramonagi) 2018年2月22日
ここまでやるか感ありますが、これとか。https://t.co/akNiEdfPvN
この辺の ::: (Not ::)も使えるかも?https://t.co/4W5zSOxQwK
RT (R) skimrの表示をカスタマイズしたい 2回目 - niszetの日記 https://t.co/1n3nsOPYR9
と追加の情報をいただきました。それぞれのページ、
を見て、ちょっとやってみた感じの内容です。
なお、この方法で関数の挙動を変えるのは上級者向けという気がします。ちゃんと内部の挙動を把握しているので後からでも分かるよ!という場合以外は1おススメしないですが、こういうことも出来るという紹介の記事ということで。
やってみる。
先の記事2つのうち、kos59125さんのブログの方で書かれている方でやってみます。
まず、inline_histの中身を確認します。
skimr::inline_hist #> function (x) #> { #> if (length(x) < 1 || all(is.na(x))) #> return(structure(" ", class = c("spark", "character"))) #> if (all(x == 0)) #> x <- x + 1 #> hist_dt <- table(cut(x, options$formats$character$width)) #> hist_dt <- hist_dt/max(hist_dt) #> structure(spark_bar(hist_dt), class = c("spark", "character")) #> } #> <environment: namespace:skimr>
問題となっているのはoptions$formats$character$width
が外部から変更できない(skimr:::options
を直接編集することが出来ない)ことでした。2回目の記事では関数を変更する方法で対応していました(ただし関数はグローバル環境に置かれている)が、今回はこの環境オブジェクトskimr:::options
をコピーした上で修正し、再びskimr
の名前空間に入れるという方法です(記事にあったやり方の通りです)
さて、やってみます。
# 一旦適当な変数に代入 rr<-skimr:::options # 変更がわかりやすいように、思い切って幅を20にしてみます。グローバル環境にある自分で作った変数なのでアクセスし放題ですね。 rr$formats$character$width <- 20 # そして、skimrの名前空間に変数rrをoptionsという名前でassignする assignInNamespace("options", rr, getNamespace("skimr"))
なお、私の今の環境ではreprexで表示させると文字化けするので以下はコンソールコピペです…2。 デフォルトの動作だと、
> skimr::inline_hist(iris$Petal.Length) ▇▁▁▂▅▅▃▁
ですが、上記の操作をした後は
> skimr::inline_hist(iris$Petal.Length) ▁▇▂▁▁▁▁▁▁▁▃▃▃▅▂▃▂▁▁▁
となります。元の関数のまま、見事に挙動が変わりましたね…。
もちろん、skimr::skim()
でも同じようになります。
> skimr::skim(iris) Skim summary statistics n obs: 150 n variables: 5 Variable type: factor variable missing complete n n_unique top_counts ordered Species 0 150 150 3 set: 50, ver: 50, vir: 50, NA: 0 FALSE Variable type: numeric variable missing complete n mean sd p0 p25 median p75 p100 hist Petal.Length 0 150 150 3.76 1.77 1 1.6 4.35 5.1 6.9 ▁▇▂▁▁▁▁▁▁▁▃▃▃▅▂▃▂▁▁▁ Petal.Width 0 150 150 1.2 0.76 0.1 0.3 1.3 1.8 2.5 ▇▂▂▁▁▁▁▂▁▅▂▃▁▁▃▂▂▁▂▂ Sepal.Length 0 150 150 5.84 0.83 4.3 5.1 5.8 6.4 7.9 ▂▂▃▇▆▁▆▇▅▆▂▇▃▆▂▁▂▁▂▁ Sepal.Width 0 150 150 3.06 0.44 2 2.8 3 3.3 4.4 ▁▁▁▁▃▃▅▃▇▇▂▃▂▁▃▁▁▁▁▁
ということで、skim()
の方でもhistの表示幅が変わっていることが確認できましたね。
パラメータを変えるのは良くないかも。関数を定義しなおして置きなおすべきかも。
ここまで書いておいてなんですが…
今回は関数を置き換える形ではなく、パラメータを管理しているskimr:::options
という環境オブジェクトの値を更新しました。
しかし注意すべきなのは、options$formats$character$width
はその構造と名前から察するに(本来?)文字列の表示する幅を制御する用途と考えられます。そのため、このようなパッケージ内部の変数を変更するのは副作用が考えられるので、パッケージ全体を確認する必要があるのかなと思います3。
なので、ちゃんと(?)関数を定義して、固有のパラメータを与えてあげる方が良いでしょう。この記事は長くなってしまったのでもう一回やるかな…4。
元に戻すには…?
ちなみにこの方法で挙動を変えた場合、RStudioを終了して再度起動したら元に戻っていました。起動ごとにlibrary()
でパッケージをロードしないといけないのと似ていますね。
パッケージ内の深いところにある関数のバグの暫定対応としてこの方法で挙動を変えた場合は、逆に起動のたびに忘れずに実行しないといけませんね。
補足
ちょっと文章的によろしくないところを全体的に直しました(2/26 1830ごろ)
最近名前空間とかスコープに関係する内容が多くなってきた気がしますね。自分なりにまとめる時期なのかもしれません。
Enjoy!!
-
つまりniszetさんにはまだ早い技術。↩
-
一貫性がなくてすみません。これについてはちょっと調べないと理解しきれていないので…↩
-
が、
iris$Species <- as.character(iris$Species)
して[^2]表示させてもfactorとcharacterで表示が変わらないような…?なので今回は副作用はないかもしれないです。しかしコード全てを見たわけではないので確かなことは言えないです…。あと、こうやってirisを直接編集しちゃダメですよ…。data(iris)
しましょうね…。ここでは簡単のためにね…。↩ -
どうかな…。
inline_hist()
とskim()
それぞれの関係とかちょっと調べることがあるので時間かかりそうです。↩