Rで条件付き書式 for ESS & Terminal
先日、R から Excel に出力する際に、条件にマッチするセルにのみ特定の書式を適用する、という id:dichika さんのエントリーがありました。
cf. Rで条件付き書式(R Advent Calendar 2011) - BOD
R を起動して作業している場合、subset などで特定の要素を抽出して表示することができますが、特定の要素の書式を変えて出力できると便利なこともあります。
ということで作りました。
colorPrint.R at master from abicky/R_funcs - GitHub
デモ
Sepal.Length が 5 より大きいレコードのフォントを赤にしてみます
Sepal.Length が 5 より大きいレコードのフォントを赤に、Sepal.Width が 3.2 より小さいレコードのフォントを青にしてみます
要 xtermStyle パッケージです。
SGR (Select Graphic Rendition) をサポートしていないと色付けされません。なので RGui や RStudio ではエスケープシーケンスが表示されるだけです。
ESS で SGR をサポートするためには M-x ansi-color-for-comint-mode-on を実行してください。
※設定をいじっていない限りはオンになっていると思います
仕組み
文字を色付けして表示すること自体は物凄く簡単です。
例えば次のコマンドを実行すると赤色で red と表示されます。
> cat("\033[31mred\n\033[0m") # 赤色で出力
red
エスケープコード(8進数で033、16進数で0x1B)に続けて [${n}m と入力することで、それ以降の文字は指定した書式で表示されます。
[${n}m にどのような値を指定できるかは例えば次のページを参照してください。
ANSI color codes
っで、もっと手軽に色付できるような関数を提供しているのが xtermStyle パッケージです。
SGR には文字色、背景色それぞれ8種類と、太字など文字の装飾の仕方を指定するコードが用意されています。
xtermStyle の style 関数では、例えば文字の色を赤、背景色を白、太字、アンダーライン入りにしたい場合には次のようなコマンドを実行します。
> style.mode("ansi") # モードを SGR用 に設定
> style("sample", fg = "red", bg = "white", font.style = c("bold", "underline"))
[1] "\033[1m\033[4m\033[31m\033[47msample\033[0m"
1が太字、4がアンダーライン、31が文字の色を赤、47が背景色を白、なので意図した通りのコードになっていますね。
colorPrint の style(または formats の style 要素) にはこの style 関数の引数 fg, bg, font.style を指定します。
ESSでも256色使いたい!!
xtermStyle ではデフォルトで xterm-color256 用のコードを生成します。
cf. The 256 color mode of xterm
これは SGR と形式が似ているのですが、別物です。
っで、ESS では ansi-color-for-comint-mode-on を実行することで SGR をサポートすることができましたが、こちらには対応していません。
そもそも、ESS はおそらく Emacs の comint mode というモードで動いていて、ansi-color-comint-mode をオンにすることで文字を出力する際に SGR を (forground-color . “black”) など、Emacs の色付け方法に変換しているだけみたいです。
comint-mode の出力を制御しているのが comint-output-filter-functions という関数群で、たいていの設定であればこの中に ansi-color-process-output という関数が含まれていて、SGR に対して何かしらの処理をします。
つまり、xterm-256color 用のコードを解釈して Emacs 用に変換してくれる関数を作成すれば ESS でも 256色扱えるようになるってことです!!
ということで、Lisp 使いの方、誰か作ってください!!