cucumber flesh

Rを中心としたデータ分析・統計解析らへんの話題をしていくだけ

日本語プロットの文字化けストレスを低減する - RStudio v1.4とraggパッケージを使う

RStudio v1.4とraggパッケージの登場でRStudio上で日本語の作図が面倒な指定不要で行えるようになりました。記事中で紹介する方法をとれば、RStudioのPlotsパネルに出力する図が文字化けしなくなります。RStudioユーザで日本語での作図を行う方にはぜひ知っていてもらいたいtipsです。

なお、この記事の元ネタは https://www.tidyverse.org/blog/2021/02/modern-text-features/ で紹介されている通りです。詳細を知りたい方はぜひこちらのページや文末の参照ページ掲載のリンクをください。

RStudioと文字化け

みなさん大好きなRStudio、開発チームが頑張っていて、日本語を含めた多言語対応が進んでいます。一方で、日本語ユーザである我々にとっては、痒いところに手が届いていないと感じる部分や使い勝手の不自由さを感じる面もあります。具体的には「文字入力」と「文字化け」、これら2つの事柄はRStudioで日本語などのマルチバイト文字列を利用する際に問題となりやすい印象にあります。

文字化けは作図を行う際に生じます。何も考えずに次のコードをRStudioで実行すると、Plotsパネルに表示されるプロットにはmain引数に指定した文字列が正しく出力されず、いわゆるトーフ状態となります。

plot(mtcars$mpg, 
     mtcars$disp, 
     main = "排気量と燃費の関係")

f:id:u_ribo:20210329174110p:plain
RStudioでの日本語プロットの文字化け

これはR標準のグラフィックス機能の他、可視化パッケージとして有名なggplot2でも生じます(結果の出力は省略します)。

library(ggplot2)
p <- 
  ggplot(mtcars, aes(mpg, disp)) +
  geom_point() +
  labs(title = "排気量と燃費の関係")
p

解決策はいずれも出力時に日本語の書体を指定することです。ここではmacOSで利用可能な日本語フォントの一種、「ヒラギノ明朝」のウェイトバリエーション「W3」を指すHiraginoSans-W3で日本語文字列を表示するようにプロットする例を示します。

par(family = "HiraginoSans-W3")
plot(mtcars$mpg, 
     mtcars$disp, 
     main = "排気量と燃費の関係")

p +
  theme_gray(base_family = "HiraginoSans-W3")

f:id:u_ribo:20210329174828p:plain

簡単なコードを追加するだけですが、毎回やるのは面倒です。またggplot2では既定の書体をtheme_set()を利用して次のように設定可能ですが、できればこの設定を意識せずに使えると楽ですよね。

こうして我々が悩まされてきた文字化けの問題がRStudioのバージョン1.4とraggパッケージによって改善される、というのが本題です。RStudio v1.4は2021年3月時点での最新版です。こちらからダウンロード可能です。また、raggはRパッケージを管理するCRANに登録されており、install.packages("ragg")を実行するとインストールされます。それでは実際にRStduio v1.4とraggを使って楽に日本語プロットを行うようにする設定を見ていきましょう。

RStudio v1.4とraggパッケージの組み合わせで文字化けを回避

RStudio v1.4とraggパッケージの用意は済んでいますか?両方が揃ったら(raggの追加は後でも可能なので、最低限RStudioを導入してください)、RStudioの環境設定(Preferences)、General、Graphicsの中のGraphic DeviceBackendの項目からAGGを適用するだけです。AGG(Anti-Grain Geometry)はraggパッケージが実装する作図デバイスのバックエンド処理で、この指定により日本語の文字化けが解消されます。一度設定すれば、RStduioを再起動しても設定は引き継がれます

以下、細かい手順を解説します。RStudioの環境設定(Preferences)を開きます。環境設定を開くと、左側にGeneral、Code、Appearanceと並ぶ画面が表示されます。画面が表示された時の位置がGeneralです。そのまま右側のボックスに目を向けましょう。こちらにはBasic、Graphics、Advancedのタブがあり、現在はBasicの設定内容が表示されていると思います。ここでGraphicsのボタンをクリックして作図に関する設定を変更します。Graphic DeviceBackendの項目が選択可能になっていますので、ここでAGGを選び、Applyボタンをクリック、OKボタンによって設定を反映させましょう。この時、もしraggパッケージがインストールされていない状態であれば、インストールを促すポップアップが表示されるので、まだの場合はここで行ってください。設定はこれだけです。

f:id:u_ribo:20210329175124p:plain

AGGを適用させたら、もう一度日本語のプロットを行ってみましょう。今度は文字化けせずに正しく日本語文字列が表示されているはずです。

注意点

上記の設定はあくまでRStduio上での作図(スクリーン上での表示)に機能します。そのため、ファイルやR Markdownでの出力の際には従来通りフォントの指定を行わないと文字化けします。ですので出力デバイスの指定にraggパッケージが提供する agg_*()の利用や、チャンクオプションでdev='ragg_png'を与えることをお勧めします。

ファイルへの出力

まずは標準の保存方法を示します。以下のコードで出力される図は日本語の文字化けがみられます。

# 日本語フォントの指定をしていないため、出力されたファイルで文字化けしている
png("out.png")
plot(mtcars$mpg, 
     mtcars$disp, 
     main = "排気量と燃費の関係")
dev.off()

AGGを利用してpng形式で保存する際はragg::agg_png()を使います。ファイル名やサイズ、解像度などの指定は基本的にはpng()と同じです。

# 日本語フォントの指定不要で文字化けしない
ragg::agg_png("out.png")
plot(mtcars$mpg, 
     mtcars$disp, 
     main = "排気量と燃費の関係")
dev.off()

ggplot2ベースでの保存、すなわちggsave()を使う場合にはさらに注意が必要です。デバイス指定の引数deviceragg::agg_pngを与えた時に出力サイズが小さくなってしまう問題が報告されています

github.com

これを防ぐためにheightwidthのオプションで出力サイズを大きくしようとすると次のエラーになります。

ggsave(plot = p, 
       filename = "out.png", 
       device = ragg::agg_png,
       height = 100
       width = 100)
#> Error:   Dimensions exceed 50 inches (height and width are specified in 'in' not pixels).
#>  If you're sure you want a plot that big, use `limitsize = FALSE`.

この場合エラーメッセージの案内に従いlimitsize = FALSEを使いましょう。

もう一点、device=ragg::agg_pngを指定すると解像度のためのオプションggsave(dpi = )は機能せず、ragg::agg_png(res = )の値が適用されます。ですが次のようにしてggsave()の中で直接ragg::agg_png(res = )の値を操作可能です。

ggsave(plot = p, 
       filename = "out.png",
       device = ragg::agg_png,
       # dpi = 320の代わりに指定
       res = 320,
       height = 2240, # pixelsでのサイズ
       width = 2240,  # pixelsでのサイズ
       limitsize = FALSE)

このあたりの処理はちょっとややこしいですが、問題解消のための機能改善が進んでいるようなので期待しましょう。

R Markdownでの利用

R Markdownでraggの機能を利用には、

  1. 図を出力するチャンクオプションにdev='ragg_png'を指定する
  2. knitr::opts_chunk(dev = "ragg_png")を設定する
  3. YAMLヘッダ部分にdev: "ragg_png"を加える

のいずれかの方法をとります。チャンクオプションdev='ragg_png'を追加する場合は以下のようになります。

 ```{r, eval=FALSE, dev='ragg_png'}
# 文字化けしない
plot(mtcars$mpg, 
     mtcars$disp, 
     main = "排気量と燃費の関係")
 ```

参考ページ

タイル形式にデータを並べて表示するtabularmapsパッケージがCRANに登録されました

新しいパッケージをCRANに登録しました。tabularmapsパッケージです。このRパッケージは以前ブログ記事にも書いた、 カラム地図を作成するためのものです。カラム地図は、行政区などの配置を表状に敷き詰めて表示することで、それぞれの位置関係をわかりやすく伝えられる利点のある可視化方法の一つです。

uribo.hatenablog.com

主要な機能は前回の記事と変わっていませんが、細かな挙動が変わったので改めて使い方を紹介します。

まずはパッケージをCRANからインストール。開発版を利用する方はGitHub経由でインストールしてください。

# CRAN版
install.packages("tabularmaps")

# 開発版
if (!requireNamespace("remotes"))
  install.packages("remotes")
remotes::install_github("uribo/tabularmaps")

tabularmapsの可視化はggplot2をベースにしているので一緒に読み込んでおくことを推奨します。

library(ggplot2)
library(tabularmaps)

tabularmapsでは任意のデータを利用可能です。また、サンプルとしていくつかのデータが備わっています。ここでは日本の都道府県の位置関係を簡略化したデータを例にしてパッケージの使い方を見ていきましょう。

カラム地図を作成する関数はtabularmaps()です。この関数の引数に対象のデータ、項目を配置させる位置を記録したx、y座標の値が含まれる変数名を指定します。加えて、項目の識別子となる変数をgroup、表示するラベルの変数名をlabelの引数にそれぞれ与えます。ここで、塗り分けの変数が存在する場合にはfill引数にその値を指定してください。

p <- 
  tabularmap(data = jpn77,
           x = x,
           y = y,
           group = jis_code,
           label = prefecture_kanji,
           fill = region_kanji,
           # 図中のlabel文字列(prefecture_kanji)の日本語表示のためのフォント指定
           family = "IPAexGothic")
p

f:id:u_ribo:20200812074924p:plain

上記の例がシンプルなカラム地図の作成方法になります。ここからアレンジしてみましょう。先ほどのコードの実行結果を保存したpオブジェクトに対して2つの関数を追加します。

p +
  scale_fill_jpregion(lang = "jp") +
  theme_tabularmap(base_family = "IPAexGothic")

f:id:u_ribo:20200812074936p:plain

scale_fill_jpregion()は日本の地方名を凡例にする際の専用の関数です。これは元々のカラム地図で使われている色を簡単に各地方に割り当てることができる関数です。ラベルが日本語・英語の場合に対応できるよう、引数langを設定します。もう一つの関数はtheme_tabularmap()です。これはggplot2::theme_minimal()の簡単なラッパです。カラム地図では特に軸ラベルなどの表記が不要なため、そうした要素を非表示にするggplot2のテーマを設定します。

以上の例では組み込みのデータセットを使いましたが、tabularmapsでは任意のデータを使ってカラム地図を作成できます。その際、各要素を配置する座標(x,y)、ラベルなどを用意してください。

タイルの角を丸くするオプション

今回のCRAN登録にあたって、各要素、つまりタイルの輪郭に対する調整を行うオプションを追加しました。カラム地図はタイルを敷き詰めたように表示するのがオリジナルですが、これを丸くして表示するオプションです。

このオプションは引数.radius_sizeで調整します。デフォルトでは2が与えられますが、この数値を大きくるするとタイルの角が丸くなります。

tabularmap(tky23,
           x,
           y,
           group = ward,
           fill = ward,
           label = ward_kanji,
           family = "IPAexGothic",
           .radius_size = 30) +
  theme_tabularmap(base_family = "IPAexGothic") +
  guides(fill = FALSE)

f:id:u_ribo:20200812074957p:plain

画面右側の図が.radius_sizeを変更したものです。同じ形で規則的に並んでいるのでカラム地図と同じような効果があると思います。

geom_tabularmps?

本当は他のggplot2関連パッケージのようにgeom_*()として関数を実装したかったのですが、今回は能力不足で至りませんでした。改善したいです。

というわけで、まだ出来たばかりでアラの多いtabularmapsパッケージですが、ぜひ使ってみてください(おかしな点があればissue報告いただけますと幸いです)。

github.com

Enjoy!

Tokyo.R#87でdata.tableパッケージの発表をしました

先日開催された第87回Tokyo.Rにおいてdata.tableパッケージに関する発表を行いました。 ここでは発表資料へのリンクと補足を書きます。

今回のスライド作成に関して、GitHubスポンサーの皆さんからの援助を受けています。 どうもありがとうございました。この場を借りて感謝いたします。

発表内容

当日の資料をspeakerdeckにアップロードしています。

speakerdeck.com

今こそ、data.tableを学ぼう! / datatable1130 - Speaker Deck

共有した画面上でカラーピッカーがデカデカと表示されたまま進行してしまったようで、どうもすみませんでした。 ご指摘ありがとうございました。

dplyrとの使い分け

data.tableパッケージはしばしば、データ操作という観点でdplyrパッケージとともに引き合いに出されます。 Rでのデータ操作といえばdplyr!そういう流れを感じますし、自分自身もdplyrファンで普段のコードもdplyr含めたtidyverseのものを使っています。 一方で時々、人様のコードを読む機会があるとdata.tableパッケージを使うものに遭遇します。 その時、data.tableで処理されたコードが読めないと困ります。

data.tableとdplyrを使ったデータ操作のコードの大きな違いは、

  • data.table: データを宣言し、[の内部でデータへの処理を記述する
  • dplyr: verbと呼ばれるデータに対する振る舞いを関数化、必要に応じてパイプ演算子%>%)によって処理を繋げていく

です。dplyrに馴染んでいる私は、パイプ演算子の出てこないコードに立ちすくんでしまうことがありました。 (逆にdata.tableをメインに使うのであったらパイプ演算子が出てくるコードを見ても謎に感じるのではないでしょうか)

data.tableでの処理は(覚えてしまうと)シンプルです。dplyrのように複数の関数の挙動を覚える必要がありません。 対象のデータ(data.tableオブジェクト)に対して [演算子を使い、その中で次の画像に示す規則で処理を記述することになります。

f:id:u_ribo:20200806085002j:plain

data.tableの文法を効率的に学習するにはdplyrでの処理と比較したら良いのではと思い、今回のスライドではdplyrのコードも掲載しています。

現実的な使い分けについてはTwitterで頂いたコメントへの返信の通り

普段使いのコードは馴染みのあるものを、ただ必要に迫られた際のためにどちらも覚えておくと良い、 と身も蓋もない話になってしまいますがそう思います。

スライド作成

フォント

発表後のチャット欄で「フォントは何を使っているか」という質問がありました。今回のスライドで用いたフォントは以下の通りです。

  • Canela Text
  • Font Awesome 5 Brands
  • FOT-ラグランパンチ
  • FOT-ロックンロール
  • Hack
  • Rockwell

このうち、「ラグランパンチ」、「ロックンロール」はフォントワークスmojimoサービスが提供するフォントパックに含まれるものです。「ラグランパンチ」はアニメ「キルラキル」やゲームソフトの「ゼルダの伝説 Breath of the world」で使われているものです。インパクトがあって見出しに適していますね。お気に入りです。

f:id:u_ribo:20200806090300j:plain

36書体が、年間定額

利用するコンピュータは一台のみの制約がありますが、切り替えもシンプルなので年間3,600円はお得です。 フォントを契約する余裕が生まれたのはGitHubスポンサーで支援してくださる方がいたためです。 発表の機会が増えるなら買ってしまえ、と契約に至りました。

カラーパレット

pals::pal.bands(c("#040A0F", "#EB6257", "#E98353", "#F1B952", "#F3CF50", "#F4EDCD"))

f:id:u_ribo:20200806083349p:plain

  • #040A0F
  • #EB6257
  • #E98353
  • #F1B952
  • #F3CF50
  • #F4EDCD

最初は違う色を使っていましたが、どうも馴染まなくて一部を変更しました。そのせいもあってか、普段は4~5色に抑えようとしているので、少し多くなってしまいました。 ドイツっぽいなーと思いますw

Enjoy!