cucumber flesh

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

🔰文字化けこわい、こわくない?

Rで解析していると文字化けに遭遇することがある。文字化けは現代妖怪の一種。怖い...って思っていた時期が私にもありました。でも、いい大人なのでお化けとも正面から向き合っていきたいと思う。というメモ。

R内で扱える文字コード

Rで利用可能な文字コードiconvlist()で出力できる、と手持ちの「R言語逆引きハンドブック」に書いてあった。ヘルプを見ながら試してみる。iconvlist()はRで扱う文字コードを文字列ベクトルで収めている(変換にはiconv()を使う)。どれだけの文字化けがRで扱えるのか数を数えてみる。

length(iconvlist())
## [1] 419

こんなにあるのか...。世界中で使われている文字コードなのでまあ当然か、とも思いつつ、この中で日本語と関係しそうなものがあるか確認。

encode.jp <- c("EUC-JP", "ISO-2022-JP", "SJIS", "SHIFT_JIS", "CP932", "UTF8")
is.element(encode.jp, iconvlist())
## [1] TRUE TRUE TRUE TRUE TRUE TRUE

きちんと対応している。

Rの関数の多くは、この文字コード処理を行う引数を備えているので、「文字化け」に出くわしたとしても適当な引数でエンコードを指定すれば良い。

日本語エンコーディング表形式のファイル

個人的によくお化けが出てくるポイント。WindowsMacUNIX)でエンコードが異なるので注意が必要。大抵の場合、ファイルの出処がWindowsならcp932(いわゆるSJIS)、MacならUTF8を引数fileEncodingで指定すれば大丈夫。

# Mac でWindows で作ったファイルを読み込む... 引数指定なし -> 👻
read.table(file = "demo.txt")
##         V1   V2   V3
## 1     var1 var2 var3
## 2 \x82\xa0    a    1
## 3 \x82\xa2    b    2
## 4 \x82\xa4    c   10
# fileEncodingでcp932を指定 -> 💫
read.table(file = "demo.txt", 
           header = TRUE,
           fileEncoding = "cp932")
##   var1 var2 var3
## 1   あ    a    1
## 2   い    b    2
## 3   う    c   10
# Windows にて Mac で作られたファイルを読み込む場合は UTF8を 指定
read.table(file = "demo_mac.txt",
           header = TRUE,
           fileEncoding = "UTF8")
##   var1 var2 var3
## 1   あ    a    1
## 2   い    b    2
## 3   う    c   10

次にパッケージを使ったデータ読み込みの場合。{data.table}{readr}{readxl}の場合。{data.table}は読み込みの段階で文字化けしているのだけど、後に変換してしまえば問題ない。{readr}は読み込みの段階でエラーとなってしまうのでなんかダメ。あれこれ試してみたけど、なんだか負けた感がある。

# {data.table}... 表形式データの読み込み関数 fread はエンコードに関する引数がない
data.table::fread(input = "demo.txt")
##        var1 var2 var3
## 1: \x82\xa0    a    1
## 2: \x82\xa2    b    2
## 3: \x82\xa4    c   10
data.table::fread(input = "demo.txt") %>% 
  dplyr::mutate(var1 = iconv(var1, from = "cp932", to = "utf8"))
##    var1 var2 var3
## 1:   あ    a    1
## 2:   い    b    2
## 3:   う    c   10
# {readr}... 【151006追記】 localeを設定し、read_delimを使えばおk
readr::read_delim("demo.txt", 
                locale = readr::locale(encoding = "cp932"),
                delim = "\t")
## Source: local data frame [3 x 3]
## 
##    var1  var2  var3
##   (chr) (chr) (int)
## 1    あ     a     1
## 2    い     b     2
## 3    う     c    10
# {readxl}... 何も指定しなくても良い!!
readxl::read_excel(path = "demo.xlsx")
## Source: local data frame [3 x 3]
## 
##   var1 var2 var3
## 1   あ    a    1
## 2   い    b    2
## 3   う    c   10

日本語文字コードエンコードされたWebサイトや日本語含むURL

http://www.sinfonica.or.jp/kanko/estrela/refer.html

趣味でUTF8でないWebサイトのURLを収集している。上記のページもそうなのだが、こうしたページは結構多い。加えて、日本のWikipediaのページはURLに日本語を使用している

ex. [https://ja.wikipedia.org/wiki/がっこうぐらし](https://ja.wikipedia.org/wiki/がっこうぐらし)!

↑こういうリンクも都度エスケープする必要がある。

そのままスクレイピングすると良くないので、こういう場合にも対応できる大人を目指したい。

# 文字化けの闇に包まれる
"http://www.sinfonica.or.jp/kanko/estrela/refer.html" %>% 
  xml2::read_html %>% rvest::html_text %>% substring(1, 50)
## Error in substring(., 1, 50): invalid multibyte string at '<8e>Q<6c>
## 
## 
## 
## 
## 
##   @ESTRELA Ql@
##   
##   
##   @ESTRELAÌfÚLÌÅÐî³êÄ¢é\tgEFAÉ¢ÄAÒ̳øð¾Äñ·éàÌÅ·B
##   @±¿çÉfڵĢé\tgEFAÍSÄt[\tgÅ·BgpÉÛµÄêØÌ¿àÍ­¶¢½µÜ¹ñB
##   @AµA{\tgÌpÉæèAªêpÒɽç©Ì¹Qª¶¶Äài´öª{\tgEFAÌàêárÅ ÁÄàjàcyÑÒÍêØÌÓCðíÈ¢àÌƳ¹Ä¢½¾«Ü·B ­ÜÅàApÒÌÓCɨ¢Ä²p­¾³¢Ü·æ¤¨è¢\µã°Ü·BÈãA²¯ÓÌã²pº³¢B
##   @ܽA{\tgEFA
# xml2::read_htmlの引数encodingでSJISを指定
"http://www.sinfonica.or.jp/kanko/estrela/refer.html" %>% 
  xml2::read_html(encoding = "SJIS") %>% 
  rvest::html_text() %>% 
  substring(1, 50)
## [1] "\n\n  \n  \n  \n  Sinfonica - ESTRELA 参考\n\n\n\n\n\n  ● ESTRE"
xml2::read_html(x = "http://had0.big.ous.ac.jp/plantsdic/angiospermae/dicotyledoneae/sympetalae/compositae/sirotaegiku/sirotaegiku.htm", encoding = "Shift_JIS") %>% 
  rvest::html_text() %>% 
  substring(1, 50)
## [1] "\r\n\r\nシロタエギク Senecio cineraria\r\n\r\n\r\n\r\n\r\n\r\nシロタエギク Sen"

URLをエスケープする関数もある。

url <- "https://ja.wikipedia.org/wiki/都道府県"
xml2::url_escape(url)
## [1] "https%3A%2F%2Fja.wikipedia.org%2Fwiki%2F%E9%83%BD%E9%81%93%E5%BA%9C%E7%9C%8C"
xml2::url_escape(url) %>% xml2::url_unescape()
## [1] "https://ja.wikipedia.org/wiki/都道府県"

所感

大文字と小文字を区別しない(ハイフン、アンダースコア、ドットの違い... ?)

対処する方法があるはずなので、文字化けに遭遇しても慌てず恐れず、落ち着いて処理していきたい。

いつものアレを貼っておく。忘れてはいけない。

github.com

参考