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

デモ

引数に何も指定しないと奇数行のフォーマットを反転させます
20120114101251

Sepal.Length が 5 より大きいレコードのフォントを赤にしてみます
20120114101252

Sepal.Length が 5 より大きいレコードのフォントを赤に、Sepal.Width が 3.2 より小さいレコードのフォントを青にしてみます
20120114101253

要 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 使いの方、誰か作ってください!!

広告
Rで単体テスト Pigで累積和を算出する
※このエントリーははてなダイアリーから移行したものです。過去のコメントなどはそちらを参照してください