代替文字を含むShift-JISのテキストファイルをRで読み込む(おまけにPythonも)
概要
Question
以下のdata.txt
というファイル名のShift-JISのテキストファイルを考えます。ただし、代替文字(Replacement Character, UnicodeでU+FFFD
)が含まれる行が存在する可能性があります。
りんご
みかん
バナナ
(以下略)
いま、このテキストファイルを、代替文字は削除したうえで1行が1要素の文字列ベクトル(c("りんご", "みかん", "バナナ"...)
)として読み込みたいです。ただし、環境はWindows, RはR>=4.2.0のバージョンとします。
Answer
回答は一例です。
readr::read_lines_raw("data.txt") %>%
stringi::stri_encode(from="Shift-JIS") %>%
stringr::str_remove_all("\ufffd")
環境
version R version 4.2.1 (2022-06-23 ucrt)
os Windows 10 x64 (build 19045)
system x86_64, mingw32
ui RStudio
language (EN)
collate Japanese_Japan.utf8
ctype Japanese_Japan.utf8
tz Asia/Tokyo
date 2022-11-21
rstudio 2022.07.1+554 Spotted Wakerobin (desktop)
(一部割愛)
readr: 2.1.3
stringi: 1.7.8
stringr: 1.4.1
説明
data.txt
に代替文字が含まれていなければ、以下で問題ありません。代替文字を含む場合でも、ファイルがUTF-8やEUC-JPの場合はencodingをそれに変えれば上記の環境で同様に問題なく読み込めました。
readr::read_lines("data.txt", locale=readr::locale(encoding="Shift-JIS"))
しかし、代替文字を含むShift-JISのファイルの場合、Error: Invalid Multibyte Sequence
というエラーが出てRStudioがクラッシュします。そのため、一旦raw形式で読み込んでから文字列に直します。raw形式で読み込む関数は、例えばreadr::read_lines_raw
があります。
次に、raw形式から文字列に変換する必要がありますが、rawToChar
を用いると文字化けしてしまいます。理由は私にはよく分かっていないのですが、こちらのStack Overflowのアンサーによると(Encoding and raw in R - Stack Overflow)、charToRaw
の関数ヘルプにはエンコーディングを考慮しないと記載があるので、rawToChar
も同様にエンコーディングが考慮されないのではないか、とのことです。R>=4.2.0の環境では日本語環境のWindowsでも文字のロケールがUTF-8ですので、辻褄が合います。
したがって、エンコーディングを考慮してrawから文字列に変換するstringi::stri_encode
を用います。
最後にstringr::str_remove_all
で代替文字である\ufffd
を削除すれば完成です。
Python版
おまけにPythonで同じことをするコードを載せておきます。バイナリモードで1行ずつ読み込んでShift-JISに変換すればOKです。line_binary.decode
でignore
とすればReplacement Characterを読み込んだ上で削除されますが、ここをreplace
としてからre.sub
で削除したり他の文字に置き換えることも可能です。
res = []
with open("data.txt", "rb") as f:
while True:
line_binary = f.readline()
line = line_binary.decode("Shift-JIS", "ignore")
if line == "":
break
res.append(line)