Hatena::ブログ(Diary)

あらびき日記 Twitter

2012-01-14

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


デモ

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

f:id:a_bicky:20120114101251p:image


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

f:id:a_bicky:20120114101252p:image


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

f:id:a_bicky:20120114101253p:image


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

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/a_bicky/20120114/1326507370