【问题标题】:Read a file in R with mixed character encodings使用混合字符编码读取 R 中的文件
【发布时间】:2019-06-03 14:56:24
【问题描述】:

我正在尝试从大多数以 UTF-8 编码(并声明 <meta charset="utf-8">)但在其他一些编码中包含一些字符串(我认为是 Windows-1252 或 ISO 8859-1)的 HTML 页面中的表格读入 R . Here's an example. 我希望将所有内容正确解码为 R 数据帧。 XML::readHTMLTable 接受 encoding 参数,但似乎不允许尝试多种编码。

那么,在 R 中,如何为输入文件的每一行尝试几种编码?在 Python 3 中,我会这样做:

with open('file', 'rb') as o:
    for line in o:
        try:
            line = line.decode('UTF-8')
        except UnicodeDecodeError:
            line = line.decode('Windows-1252')

【问题讨论】:

标签: html r character-encoding


【解决方案1】:

似乎确实有用于猜测字符编码的 R 库函数,例如 stringi::stri_enc_detect,但如果可能,最好使用更简单的确定性方法,按顺序尝试一组固定的编码。看起来最好的方法是利用这样一个事实:当iconv 无法转换字符串时,它会返回NA

linewise.decode = function(path)
    sapply(readLines(path), USE.NAMES = F, function(line) {
        if (validUTF8(line))
            return(line)
        l2 = iconv(line, "Windows-1252", "UTF-8")
        if (!is.na(l2))
            return(l2)
        l2 = iconv(line, "Shift-JIS", "UTF-8")
        if (!is.na(l2))
            return(l2)
        stop("Encoding not detected")
    })

如果你用

创建一个测试文件
$ python3 -c 'with open("inptest", "wb") as o: o.write(b"This line is ASCII\n" + "This line is UTF-8: I like π\n".encode("UTF-8") + "This line is Windows-1252: Müller\n".encode("Windows-1252") + "This line is Shift-JIS: ハローワールド\n".encode("Shift-JIS"))'

然后linewise.decode("inptest") 确实返回

[1] "This line is ASCII"                    
[2] "This line is UTF-8: I like π"          
[3] "This line is Windows-1252: Müller"     
[4] "This line is Shift-JIS: ハローワールド"

要将linewise.decodeXML::readHTMLTable 一起使用,只需说出XML::readHTMLTable(linewise.decode("http://example.com")) 之类的内容即可。

【讨论】:

  • 不是一定要反过来iconv(lines, from = "UTF-8", to = "Windows-1252")吗?
  • @BigDataScientist 不,我希望一切最终都使用 UTF-8(因为事实证明 R 没有像 Python 3 的 str 这样的无二进制表示的字符串类型),并且Windows-1252 是我想要更改的某些行的预先存在的编码。
猜你喜欢
  • 1970-01-01
  • 2011-08-05
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多