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

WindowsでRのロケールを設定するときのメモ

ロケールとは。

http://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Localesによると、

A locale is a description of the local environment of the user, including the preferred language, the encoding of characters, the currency used and its conventions, and so on. Aspects of the locale are accessed by the R functions Sys.getlocale and Sys.localeconv.

The system of naming locales is OS-specific. There is quite wide agreement on schemes, but not on the details of their implementation.

とある。なんとなく合意はあるけど、ロケール名はOSによって違うよ、と。

ロケールは以下を特定する必要がある。

A human language. These are generally specified by a lower-case two-character abbreviation following ISO 639 (see e.g. http://en.wikipedia.org/wiki/ISO_639-1).

ひとつめは、言語。小文字二文字であらわされるもの。jaとかenみたいなの。

A ‘territory’, used mainly to specify the currency. These are generally specified by an upper-case two-character abbreviation following ISO 3166 (see e.g. http://en.wikipedia.org/wiki/ISO_3166).

ふたつめは、領域。大文字2つであらわされるもの。JPとかUSみたいなの。

A charset encoding, which determines both how a byte stream should be divided into characters, and which characters the subsequences of bytes represent. Sometimes the combination of language and territory is used to specify the encoding, for example to distinguish between traditional and simplified Chinese.

みっつめは、文字コードUTF-8とかShift_JISみたいなの。

あと、オプションで@euroみたいな修飾子が付くことがある。方言を示すような場合とか?

Optionally, a modifier, for example to indicate that Austria is to be considered pre- or post-Euro. The modifier is also used to indicate the script (@latin, @cyrillic for Serbian, @iqtelif) or language dialect (e.g. @saaho, a dialect of Afar, and @bokmal and @nynorsk, dialects of Norwegian regarded by some OSes as separate languages, no and nn).

Linuxの場合

http://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Locales-under-Unix_002dalikes

XPGというやつで定められてるとかなんとかかんとか。(Rじゃなくて)シェルでlocale -aってやると一覧が見れる。あとman localeってやってもいろいろ見れるらしいです。

Macの場合

http://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Locales-under-OS-X

手元に環境がなくてよく分からないので省略。独自路線を突っ走ってる、みたいなこと書いてるけど、たぶんLinuxに近い気がします。

Windowsの場合

http://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Locales-under-Windows

トリッキーだから注意せよ、と。例えば、chinese繁体字らしい。

で、このドキュメントからポイントされてるMSのドキュメントの最新版はたぶんこれ:Locale Names, Languages, and Country/Region Strings

これによると、

locale :: "locale_name"
        | "language[_country_region[.code_page]]"
        | ".code_page"
        | "C"
        | ""
        | NULL

が指定できるらしい。実際やってみます。

locale_name

説明はこんな感じ。

The locale name form—for example, en-US for English (United States) or bs-Cyrl-BA for Bosnian (Cyrillic, Bosnia and Herzegovina)—is preferred. The set of locale names is described in Locale Names. For a list of supported locale names by Windows operating system version, see the Culture Name column of the National Language Support (NLS) API Reference. This resource lists the supported language, script, and region parts of the locale names. For information about the supported locale names that have non-default sort orders, see the Locale name column in Sort Order Identifiers.

さらにここでポイントされているLocale Names (Windows)によると、

Generally, the pattern - is used. Here, language is a lowercase ISO 639 language code. The codes from ISO 639-1 are used when available. Otherwise, codes from ISO 639-2/T are used. REGION specifies an uppercase ISO 3166-1 country/region identifier. For example, the locale name for English (United States) is "en-US" and the locale name for Divehi (Maldives) is "dv-MV".

とあって、利用可能なロケール名のリストにも入っているja-JPが使えそうなものだが、なぜか使えない...

Sys.setlocale("LC_ALL", 'ja-JP')
#> [1] ""
#> Warning message:
#> In Sys.setlocale("LC_ALL", "ja-JP") :
#>   OS reports request to set locale to "ja-JP" cannot be honored

あきらめて次へ。

language[_country_region[.code_page]]

langageのリストはこれで、country/regionのリストはこれということだが、どちらも最新版のリストには日本が見当たらない...。よくわかりませんが、languageはJapanese/ja、region/countryはJapan/JPNみたいです。

code pageというのは、Windows文字コードに割り当てている番号で、日本語(というかShift_JIS)は932です。

Windows code page - Wikipedia, the free encyclopedia

ためしてみます。

まず、languageだけ。

Sys.setlocale("LC_ALL", 'Japanese')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"
Sys.setlocale("LC_ALL", 'ja')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"
Sys.setlocale("LC_ALL", 'jA')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"

フルネームでも省略形でもいけました。Windowsなので当たり前っちゃ当たり前ですが、大文字小文字は無視されます。

次、language_countryのパターン。

Sys.setlocale("LC_ALL", 'Japanese_Japan')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"
Sys.setlocale("LC_ALL", 'Ja_Japan')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"
Sys.setlocale("LC_ALL", 'Japanese_jpn')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"
Sys.setlocale("LC_ALL", 'ja_jpn')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"

こちらも、フルネームでも省略形でもどちらでもいけました。

最後に、language_country.codepageのパターン

Sys.setlocale("LC_ALL", 'Japanese_Japan.932')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"

いけました。

ちなみに、これは混ぜたりもできるみたいです。(869はGreekのコード)

Sys.setlocale("LC_ALL", 'English_Japan.932')
#> [1] "LC_COLLATE=English_Japan.932;LC_CTYPE=English_Japan.932;LC_MONETARY=English_Japan.932;LC_NUMERIC=C;LC_TIME=English_Japan.932"
Sys.setlocale("LC_ALL", 'Japanese_US.869')
#> [1] "LC_COLLATE=Japanese_United States.869;LC_CTYPE=Japanese_United States.869;LC_MONETARY=Japanese_United States.869;LC_NUMERIC=C;LC_TIME=Japanese_United States.869"

わけが分からないよ...

.code_page

code pageだけで指定することもできます。languageとregion/countryはシステムデフォルトのが使われるみたいです。

Sys.setlocale("LC_ALL", '.932')
#> [1] "LC_COLLATE=Japanese_Japan.932;LC_CTYPE=Japanese_Japan.932;LC_MONETARY=Japanese_Japan.932;LC_NUMERIC=C;LC_TIME=Japanese_Japan.932"
Sys.setlocale("LC_ALL", '.869')
#> [1] "LC_COLLATE=Japanese_Japan.869;LC_CTYPE=Japanese_Japan.869;LC_MONETARY=Japanese_Japan.869;LC_NUMERIC=C;LC_TIME=Japanese_Japan.869
C

このロケールなんだろうなとずっと思ってたんですけど、ここはちゃんと説明読んでみましょう。

A locale value of C specifies the minimal ANSI conforming environment for C translation. The C locale assumes that every char data type is 1 byte and its value is always less than 256. If locale points to an empty string, the locale is the implementation-defined native environment.

すべての文字が1バイトであるとして扱う、と。なるほど。こうすることで、余計な解釈をして文字化けするなんていう事態が回避されるんですね。納得。

感想

やっぱりWindowsならロケールCが無難なんですね。すごく遠回りした感。。。