付録 A — エンコーディングの問題

エンコーディングの問題とは、いわゆる「文字化け」のことです。

A.1 文字化けが起こる理由

簡単に言うと、エンコーディングとは人間が理解可能な自然言語から機械が理解可能な記号への「翻訳方法」です。エンコードとデコードで異なる方式を用いると、適切な文字に翻訳できず、文字化けが起こります。

エンコーディングの方法は以下のように、使用しているOSによって変わります。

  • Mac, Linux: UTF-8
  • Windows: Shift-JISやCP932

つまり、Macなどで作成され、すなわちUTF-8でエンコードしたデータをWindowsでShift-JISなどでデコードしようとすると文字化けが起こります(その逆もしかり)。

WindowsでもUTF-8となる場合

Windows 10以上でR 4.2以上を使っている場合はUTF-8がデフォルトのエンコーディングになります。この場合は、以下の説明のRに関する箇所においてはMax, Linuxとして読んでください。

したがって、対処法は次の通りになります。

  • Mac, Linuxで文字化けが起こる\(\leadsto\)データはShift-JISなどでエンコードされているので、そのように指定する。
  • Windowsで文字化けが起こる\(\leadsto\)データはUTF-8などでエンコードされているので、そのように指定する。

なお、UTF-8が様々な言語に対応しているものなので、データなどを保存する際はこちらを使うほうがベターです。

A.2 ロケールの確認

ロケールとは、ざっくり言うと、PCにおける言語や国・地域の設定のことです。ロケールを確認すると、デフォルトのエンコーディングも分かります。

R
Sys.getlocale()
[1] "LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=ja_JP.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=ja_JP.UTF-8;LC_MESSAGES=en_US.UTF-8;LC_PAPER=ja_JP.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=ja_JP.UTF-8;LC_IDENTIFICATION=C"
Python
import sys

sys.getdefaultencoding()
'utf-8'

僕はLinuxを使っているので、UTF-8がデフォルトのエンコーディングです。

A.3 データの文字化け

UTF-8でエンコーディングされたデータShift-JISでエンコーディングされたデータをダウンロードします。

A.3.1 問題の確認

まず、UTF-8のデータを読み込みます。MacやLinuxの場合は問題なく読み込めるはずです。一方で、Windowsの場合はエラーが表示されるはずです。

R (base)
read.csv("data/data_utf8.csv")
  桃太郎
1   イヌ
2   サル
3   キジ
R (tidyverse)
library(tidyverse)

read_csv("data/data_utf8.csv")
# A tibble: 3 × 1
  桃太郎
  <chr> 
1 イヌ  
2 サル  
3 キジ  
Python
import pandas as pd

pd.read_csv('data/data_utf8.csv')
  桃太郎
0  イヌ
1  サル
2  キジ

逆に、Max, LinuxではShift-JISのデータは読み込めず、Windowsでは読み込めるはずです。

R (base)
read.csv("data/data_sjis.csv")
Error in make.names(col.names, unique = TRUE): invalid multibyte string at '<93><8d><91><be><98>Y'
R (tidyverse)
read_csv("data/data_sjis.csv")
Error in nchar(x, "width"): invalid multibyte string, element 1
Python
pd.read_csv('data/data_sjis.csv')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 0: invalid start byte

A.3.2 対処法

データを読み込む時にエンコーディング方法を明示することで解決できます。

R (base)
read.csv("data/data_sjis.csv", fileEncoding = "Shift-JIS")
  桃太郎
1   イヌ
2   サル
3   キジ
R (tidyverse)
read_csv("data/data_sjis.csv", locale = locale(encoding = "Shift-JIS"))
# A tibble: 3 × 1
  桃太郎
  <chr> 
1 イヌ  
2 サル  
3 キジ  
Python
pd.read_csv('data/data_sjis.csv', encoding='Shift-JIS')
  桃太郎
0  イヌ
1  サル
2  キジ

“Shift-JIS”を”UTF-8”に変更すれば、UTF-8のデータを読み込むことができます。

R (base)
read.csv("data/data_utf8.csv", fileEncoding = "UTF-8")
  桃太郎
1   イヌ
2   サル
3   キジ
R (tidyverse)
read_csv("data/data_utf8.csv", locale = locale(encoding = "UTF-8"))
# A tibble: 3 × 1
  桃太郎
  <chr> 
1 イヌ  
2 サル  
3 キジ  
Python
pd.read_csv('data/data_utf8.csv', encoding='UTF-8')
  桃太郎
0  イヌ
1  サル
2  キジ
表計算ソフトで見る場合

例えば、UTF-8の.csvファイルをWindowsのエクセルで開くと文字化けが起こります。Libre Officeという無料のオフィスソフトではエンコーディングを指定してファイルを開くことができるので、こちらで開くことを勧めます。

A.4 スクリプトの文字化け

UTF-8でエンコーディングされたスクリプトShift-JISでエンコーディングされたスクリプトをダウンロードします。

A.4.1 問題の確認

Mac. LinuxでUTF-8のスクリプトを開くと正しく表示されますが、Windowsでは表示されないはずです。

同様に、Shift-JISの方はWindowsで正しく表示され、Mac, Linuxでは文字化けが起こるはずです。

  • Rスクリプトですが、原理はPythonスクリプトと同様です。VIsual Studio Codeなどで開いてみてください。

A.4.2 対処法

RStudioの場合、メニューの中のFileReopen with Encoding...というのがあるので、UTF-8を選択します。さらにSet as default encoding for source filesにチェックを入れることで今後はUTF-8で表示されます。

今後、文字化けが起こる場合はShift-JISでエンコーディングしたファイルのはずなので、Reopen with Encoding...Shift-JISを選択してファイルを開きます。

Visual Studio Codeの場合、右下にエンコーディングが書かれているので、それをクリックし、Reopen with Encodingをクリックし、適当なエンコーディングを選択します。

A.5 エンコーディングの確認

ファイルのエンコーディングを確認することが可能です。どれくらい信頼していいのかは分かりません。

R (tidyverse)
guess_encoding("data/data_sjis.csv")
# A tibble: 1 × 2
  encoding     confidence
  <chr>             <dbl>
1 windows-1252       0.23
Python
import chardet

with open('data/data_sjis.csv', 'rb') as f:
  c = f.read()
  chardet.detect(c)
{'encoding': 'SHIFT_JIS', 'confidence': 0.99, 'language': 'Japanese'}

A.6 文字化けしない保存

A.6.1 データの保存

データを保存する際は(そもそもマルチバイト文字を避けるべきですが)UTF-8で保存するほうが良いでしょう。

R (base)
write.csv(..., "...", fileEncoding = "UTF-8")
R (tidyverse)
write_excel_csv("...")
  • tidyverseではwrite_excel_csv()を使うことで、エクセルでも文字化けしないようにできます。
Python
....to_csv('...', encoding='UTF-8_sig')
  • pandasではencoding='UTF-8_sig'とすることで、エクセルでも文字化けしないようにできます。

A.6.2 スクリプトの保存

RStudioの場合、Fileの中のSave with Encoding...UTF-8を選択してください。ここでもUTF-8がデフォルトになるようにチェックを入れておきましょう。

A.6.3 画像の保存

Macで画像を保存する際に、日本語が文字化けするらしいです。対処法は以下の通りです。

  • フォント名HiraKakuProN-W3は例です。
R (base)
par(family = "HiraKakuProN-W3")
R (tidyverse)
theme_set(theme_grey(base_family = "HiraKakuProN-W3"))
Python (matplotlib)
plt.rcParams['font.family'] = 'HiraKakuProN-W3'
Python (seaborn)
sns.set(font='HiraKakuProN-W3')