首页 文章

无需内存复制即可有效更改R字符编码(编码功能)

提问于
浏览
1

我经常导入巨大的Excel文件,因此在Windows 7上使用包 openxlsxreadxlxlsx::read.xlsx[2] 太慢) .

这些包没有指定编码的选项,因此我必须将字符串列的编码标记从“unknown”(native = Windows codepage 1252)更改为UTF-8,这是Excel的XLSX文件的标准编码 .

What is the most efficient way to change R's encoding marker of "strings" (character vectors) without causing the original strings to be copied?

R有 Encoding()enc2utf8 来更改编码标记,我只使用它来修复错误的编码标记,而不更改字符串的原始字节 .

即使 Encoding() 不应该更改字符串本身的字节(=不转换字符串,如 iconv ),字符串也会被复制一次或多次:

> x <- "fa\xE7ile"
> x
[1] "fa\xe7ile"
> charToRaw(x)
[1] 66 61 e7 69 6c 65
> tracemem(x)
[1] "<0x47030f8>"
> Encoding(x)
[1] "unknown"
> Encoding(x) <- "latin1"
tracemem[0x47030f8 -> 0x4463118]: 
tracemem[0x4463118 -> 0x44630e8]: Encoding<- 
> x
[1] "façile"   
> charToRaw(x)
[1] 66 61 e7 69 6c 65
> enc2utf8(x)
tracemem[0x44630e8 -> 0x4706e38]: 
[1] "façile"
> charToRaw(x)
[1] 66 61 e7 69 6c 65

PS: enc2utf8 的帮助声称"They are primitive functions, designed to do minimal copying."但仍然复制字符串一次 .

1 回答

  • 2

    您可以通过直接调用函数的赋值版本来避免其中一个副本,

    `Encoding<-`(x,"latin1")
    

    我的猜测是剩下的副本是不可避免的,因为看起来所有字符(R中字符串的更常见名称)对象都是在 NAMED 属性设置为2的情况下创建的 . 你可以通过检查这个,

    x <- "a"
    .Internal(inspect(x))
    

    在干净的R会话中 . (而不是在RStudio中,我相信RStudio以可能误导的方式人为地混淆 NAMED 属性 . )如果我真的推测,我会使用全局哈希表来表示所有字符向量,这样可以提供很多性能通常对字符向量进行改进,但在某些情况下可能会产生一些额外的复制 .

    有关这些复制问题的进一步阅读可以在here找到 .

相关问题