更改R字符编码,无需复制内存(编码function)

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

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

什么是最有效的方式来改变R的“string”(字符向量)的编码标记,而不会导致原始string被复制?

R有Encoding()enc2utf8来改变编码标记,我只用它来修复错误的编码标记而不改变string的原始字节。

即使Encoding()不应该改变string本身的字节(=不能像iconv那样转换string),string会被复制一次或多次:

 > 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的帮助声称“它们是原始的function,旨在做最小限度的复制”。 但仍然复制一次string。

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

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

我的猜测是,剩下的副本是不可避免的,因为看起来,所有的字符(R中string的更常见的名字)是用它们的NAMED属性设置为2来创build的。你可以通过检查这个,

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

在一个干净的R会议。 (而不是在RStudio,我相信RStudio人为地用NAMED属性NAMED可能是误导的方式。)如果我真的推测,我猜想这是某种程度上与R使用全局哈希表的所有字符vector,这可以大大提高字符vector的性能,但是在某些情况下可能会导致一些额外的复制。

进一步阅读这些复制问题可以在这里find。