niszetの日記

細かい情報を載せていくブログ

(R) skimrのヒストグラムがwindows上のknitr下ではうまく表示されない(未解決)

文字コードの問題なのでwindows限定だと思いますが

さて、人類はいつまで文字コードに悩まされなくてはいけないのでしょうか。Windows上でしか動作しないものもあるので、ともに生きる道を探るしかありませんね…。

さて、タイトルの通りskimrヒストグラムknitr環境下ではうまく表示できないという問題があります。未解決です。

同様の質問はググると沢山出てきて、例えば以下にも。

community.rstudio.com

さて、skimrについては以前も記事に書きました(3回目まである)

niszet.hatenablog.com

が、簡単に説明するとskimr::skim()は強化版summary()で、たとえばこんな感じに表示できます。(コンソール上では)

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

これをRMarkdown中で下記のように(```の前の\ははてなブログ上でのコードハイライトの関係です。コピペする場合は取ってください)

\---
title: "skimr_test"
author: "niszet"
date: "2018年5月26日"
output: html_document
\---

\```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
\```

\```{r}
skimr::skim(iris)
\```

書いてknitrでhtmlへの返還を実行すると、下記

f:id:niszet:20180526232358p:plain

のようになります。これは、中間生成物のMarkdownを残して(keep_mdTRUEに設定する)確認してもこの状態だったので、これはPandocではなくてknitrの仕業ということになります。

この、RMarkdownがhtmlなどのファイルに変換される仕組みの裏側については一年ほど前に🐘さんがTokyoR#61で発表されています。1

R Markdownの内部と テンプレート開発

正直これを理解するのはちょっと難しいのと、理解できていなくてもRMarkdownは使えますのでご安心を。RMarkdown周りを自分好みにカスタマイズしたい…!という方は是非読みましょう。

で、knitr周りを結構調べてはみたものの解決策は特に見つからず。しかし、このままでは文字化けした大量の記号を眺めるだけになってしまうのでなんとかしたい。

これは、skimrの記事の2回目の方法を使って対応できます。

niszet.hatenablog.com

が、今回はもうちょっと綺麗に行きます。exportされていない関数ですが、get_funs()を使うことで一旦関数たちを抜き出して必要な部分を修正して入れ直すという方法です。

exportこそされていませんが、この関数はインターフェースが綺麗に作られているので普段使っても問題はないのではないかなーと思います(が、予告なく変更は入るかもしれませんね)

今回、ヒストグラムが不要なのでhistという要素そのものを消してしまうという方法です。リストの要素を丸ごと消すならNULLの代入ですね。

hoge <- skimr:::get_funs("numeric")
hoge[["hist"]] <- NULL
skimr:::set_options(type = "numeric", env = "functions", append = FALSE, newopts = hoge)
skimr::skim(iris)

これを先のチャンクと入れ替えると、下記のような出力になります。

f:id:niszet:20180526232255p:plain

hist以外にも不要な列があれば、都度NULLを代入して消せばOKです。また、ここではnumericのみ対応していますが、integerなど他の型についても同様に出来ます。

コレ、いつか直るのだろうか…。

追記(2018/6/10)

issueにあがっていた。あと、上記の方法についてはもっと良い方法があるので追って全訂の予定です。

github.com

Enjoy!!


  1. 完全に余談ですが、この回が私がTokyoRに参加した第一回目です。懐かしいですねぇ…。この時は勉強会初参加、ブログも書いて1か月、R触ってようやく半年くらいでしたね。おっさんなのにずいぶんと気持ちがフレッシュだった。いや、今もですけどね。この時にもちょっとだけkazutanさんとも話せたんですよねぇ。大仏様ともここで初めて会った…って話が長くなるな…。