niszetの日記

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

(R) skimrの表示をカスタマイズしたい 1回目

そのまま使っても便利ですが、カスタマイズすることで自分好みに設定できます

skimrって何?という方はまずは下記の記事をご覧ください。

niszet.hatenablog.com

なお、現時点のCRAN版skimrは1.0.1で、ここに書く内容はvignette: Using_skimrgithub上のREADME.mdに書かれていることがほとんどです。そちらを読んだ方が早いかもしれませんね。

vignette("Using_skimr")

本題

さて、強化版summary()であるskimrパッケージの関数skim()には、同パッケージのskim_with()関数によって、data.frameの各列の型に対応して表示のさせ方を変えることが出来ます。

そもそもあの関数は一体何をどう計算し表示しているのだろうか…?ということから始めて、上記のvignetteを追いかけながら自分好みにカスタマイズする方法を調べていきます。

まずはデフォルトの設定での表示について把握する

まずはデフォルトの表示について改めて確認してみます。とりあえずお手頃irisさんで、どうぞ1

> 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 ▁▂▅▇▃▂▁▁

最初にirisのデータフレームが150行5列のデータであることを表示した後に、factorとnumericそれぞれについて表示していますね。そして、それぞれのデータ型によって表示させる内容が異なることがわかります。

さてこの表示させる内容がどう設定されているのかを調べるには、skimr::get_skimmers()でデータ型毎に一覧を得ることが出来ます。
しかし、これをそのまま実行するとlistのlistが返ってきてコンソール上にだらっと表示されてしまい、非常に見づらいのでView()の出番です2。 というわけで、ほいっと。

View(skimr::get_skimmers())

で、こうです。

f:id:niszet:20180217104723p:plain

ここではnumericの項目を一つ掘って展開・表示していますが、このlistの要素の並びのmissing, complete, n ... と先のskim()の結果の表示の各列に対応していることがわかります。これらの関数が適用されてskimr::skim()にて表示されるのですね。さらにこの各関数についても見れますが、ちょっと話が発散してしまうので詳細は割愛。深堀するならR言語徹底解説かなぁ。functionの構成がわかると理解が深まると思いますが、とりあえずこのお話の中ではあまり関係ないので…。

さて他の型、例えばfactorについても同様の構成となっていて各型に対してどの関数たちを使用して処理・表示するかを定義している形になっています。

このskimr::get_skimmers()での表示は現在設定されている関数群を表示するので、このあとで使用するskim_with()関数で内容を更新した後も、現在のskim()で表示される内容(関数)が見れます。

実際にskim_with()を使用してみる。

前置きが長くなってしまいましたが、実際にskim_with()を使用してskim()の表示のさせ方が変わるところを見てみます。 vignetteの例の通りですが、skim()で表示させたい項目をlistでまとめる形で作ります。ここで、=の左はskim()で表示させたときの列名になります。右側が関数の名前(呼び出しではない)という形になりますね。purrr::partialは第一引数の関数の引数の一部に値を指定しているのですね。

funs <- list(iqr = IQR,
quantile = purrr::partial(quantile, probs = .99))

partialで躓いたときはこちらのid:yutannnihilationさんの記事が参考になるかなと思います。 notchained.hatenablog.com

さて、先の変数funsをskim_with()に与えます。これはnumeric型に対して適用したいので、下記のように。第二引数のappend = TRUEは元の関数たちを残すかどうかです。残す場合はこのように

skim_with(numeric = funs, append = TRUE)

このとき、関数群は

View(skimr::get_skimmers())

で見てみると、末尾に2つ追加されていることがわかります。

f:id:niszet:20180217220215p:plain

そして、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 iqr quantile
 Petal.Length       0      150 150 3.76 1.77 1   1.6   4.35 5.1  6.9 ▇▁▁▂▅▅▃▁ 3.5     6.7 
  Petal.Width       0      150 150 1.2  0.76 0.1 0.3   1.3  1.8  2.5 ▇▁▁▅▃▃▂▂ 1.5     2.5 
 Sepal.Length       0      150 150 5.84 0.83 4.3 5.1   5.8  6.4  7.9 ▂▇▅▇▆▅▂▂ 1.3     7.7 
  Sepal.Width       0      150 150 3.06 0.44 2   2.8   3    3.3  4.4 ▁▂▅▇▃▂▁▁ 0.5     4.15

次。第二引数をFALSEにした場合は、

skim_with(numeric = funs, append = FALSE)

として、関数たちを見てみると、

View(skimr::get_skimmers())

f:id:niszet:20180217220241p:plain

となりました。

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 iqr quantile
 Petal.Length 3.5     6.7 
  Petal.Width 1.5     2.5 
 Sepal.Length 1.3     7.7 
  Sepal.Width 0.5     4.15

で、自分で追加した部分だけが表示されました。

元に戻すときは?

skim_with_defaults() を使用すると、元の(デフォルトの)設定に戻ります。困ったらこのコマンドを実行しましょう。

順序を入れ替えるときは?

表示順序を入れ替えたい時などはエクスポートされていない要素ですがskimr:::.defaultを使って関数を持ってくるのがいいのかな…あまり良い方法ではないのですが、エクスポートされている関数でデフォルトで設定されている関数を取り出してくる方法が見つからなかったので…。

p0の項目だけを持ってくるだけならば例えばこんな感じです。

skim_with(numeric=list(p0=skimr:::.default[["numeric"]][["p0"]]), append=FALSE)

1項目でもlist()で囲うこと、列に表示する名前=関数名の形で書くこと、が注意点ですね。なお、[["numeric"]]とかはView(skimr:::.default)で表示させた状態で使いたい関数の右の方でマウスカーソルを置いて[ ⇐] `のようなアイコンをクリックしてコンソールに持って来ましょう。これも以前書いたViewの記事で紹介したとおりです。

> 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  p0
 Petal.Length 1  
  Petal.Width 0.1
 Sepal.Length 4.3
  Sepal.Width 2  

ということで、skimrパッケージのskim関数の表示のさせ方を色々といじってみました。
長くなってしまったのでViewの時と同じように複数回に分けて書こうと思います。続きます。

Enjoy!!


  1. 最近は出来るだけreprexの書式にしようとしていますが、strみたいにコンソールに出力するタイプはその出力のままの方がわかりやすいという観点で書き方を変えています(コマンドの入力行に > がつく、要するにコンソールからコピペそのまま)

  2. RStudio IDE上での使用を想定しています。詳しくはこのシリーズを参考にしてください。(R) View関数に関して(1回目) - niszetの日記