読者です 読者をやめる 読者になる 読者になる

小ネタ:Rでパッケージ読み込み時に日本語のメッセージを出す

こないだつくった国土数値情報ダウンロードサービスAPIのRパッケージですが、

Web APIにはこんな利用規約があります。

クレジット表示

API機能を使用したサービスを公開される場合には、同一画面上に下記のクレジット表示をお願いします。 『このサービスは、「国土交通省 国土数値情報(カテゴリ名)」をもとに加工者が作成』 以上が実現出来ない場合は、個別にご相談下さい。
Web API(試行版)

Rパッケージは「サービス」ではないから別にいいのでは?と言う気もするんですけど、よく分からないしまあ出しといた方が親切なので日本語でそれっぽいメッセージを出すようにしました。

library(kokudosuuchi)
#> このサービスは、「国土交通省 国土数値情報(カテゴリ名)」をもとに加工者が作成
#> 以下の国土数値情報ダウンロードサービスの利用約款をご確認の上ご利用ください:
#> 
#> http://nlftp.mlit.go.jp/ksj/other/yakkan.html

えっ、日本語で???

と、思う方もいるでしょう。経験者の方は知っていると思いますが、非ASCII文字が含まれているとパッケージビルド時にこんな感じのエラーがでます(...よね?)。

Error in parse(text = lines, n = -1, srcfile = srcfile) : 
  invalid multibyte character in parser at line 7
Calls: suppressPackageStartupMessages ... in_dir -> force -> source_many -> source_one -> parse
In addition: Warning message:
In grepl("\n", lines, fixed = TRUE) :
  input string 7 is invalid in this locale
Execution halted

Exited with status 1.

どうすればいいかというと、やり方は2つあります。

エスケープする

R Packagesにも記述があります。

If you’re planning on submitting your package to CRAN, you must use only ASCII characters in your .R files. You can still include unicode characters in strings, but you need to use the special unicode escape "\u1234" format. The easiest way to do that is to use stringi::stri_escape_unicode():
(R code · R packages)

"\uXXXX"というエスケープならパッケージ中で使うことができて、stringi::stri_escape_unicode()を使うと文字列をそのエスケープ形式に変換してくれます。

stringi::stri_escape_unicode("ようこそ")
#> [1] "\\u3088\\u3046\\u3053\\u305d"

これを.onAttachに書いておけば大丈夫です

.onAttach <- function(...) {
  packageStartupMessage("\\u3088\\u3046\\u3053\\u305d")
}

文字列ではなくRのデータとして保存する

もう一つの方法は、文字列としてコードに書いておくのではなく、Rのデータとして保存する方法です。これには、devtools::use_data()が便利です。内部的にしか使わないので、internal = TRUEを指定します。(internal = FALSEdata()で読み込むデータセットとかに使うみたいです)。

KSJcredit <- iconv("このサービスは、云々かんぬん", to = "UTF-8")

devtools::use_data(KSJcredit, internal = TRUE)
#> Saving KSJcredit to R/sysdata.rda

ここで重要なのは、文字列をUTF-8にしておくことです。こうしておくことでWindowsからもLinuxからも読めます。「えっ、UTF-8だとWindowsで文字化けするんじゃ??」と思った人、あれはEncodingが指定されてない場合の話です。iconv(..., to = "UTF-8")で変換された後のオブジェクトはちゃんとEncodingも設定されているので大丈夫です。

Encoding(KSJcredit)
[1] "UTF-8"

ということで、このcharacterオブジェクト名を.onAttachに書いておけば大丈夫です。

.onAttach <- function(...) {
  packageStartupMessage(KSJcredit)
}

私はこっちの方法でやりました。

github.com