edd*_*ddi 9 r internals data.table
这个问题源自以下data.table错误报告 - #4978,但我将使用一个data.frame例子来说明这不是一个data.table特定的问题:
考虑以下:
df = data.frame(a = 1, hø = 1)
identical(names(df), c("a", "hø"))
#[1] TRUE
.Internal(inspect(names(df)))
#@0x0000000007b27458 16 STRSXP g0c2 [NAM(2)] (len=2, tl=0)
# @0x000000000ee604c0 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "a"
# @0x0000000007cfa910 09 CHARSXP g0c1 [gp=0x21] [cached] "hø"
.Internal(inspect(c("a", "hø")))
#@0x0000000007b274c8 16 STRSXP g0c2 [] (len=2, tl=0)
# @0x000000000ee604c0 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "a"
# @0x0000000007cfa970 09 CHARSXP g0c1 [gp=0x24,ATT] [latin1] [cached] "hø"
Run Code Online (Sandbox Code Playgroud)
请注意,尽管identical认为两者是相同的,但是底层字符串缓存将"hø"存储在两个不同的位置,同时将"a"存储在一个中.怎么了?这是一个R字符串缓存错误吗?
其重要的原因是%chin%在这里失败(因为上述差异):
library(data.table)
"a" %chin% names(df)
#[1] TRUE
"hø" %chin% names(df)
#[1] FALSE
Run Code Online (Sandbox Code Playgroud)
"hø"当直接打印到控制台时,被标记为UTF-8编码.你可以强迫它使用enc2native本机,这个问题就会消失,但是我仍然在研究为什么这是......
Encoding("hø")
# [1] "UTF-8"
.Internal( inspect( c( "a" , enc2native("hø") ) ) )
#@1081d60a0 16 STRSXP g0c2 [] (len=2, tl=0)
# @100af87d8 09 CHARSXP g1c1 [MARK,gp=0x61] [ASCII] [cached] "a"
# @1081e3a08 09 CHARSXP g1c1 [MARK,gp=0x21] [cached] "hø"
enc2native("hø") %chin% names(df)
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)
在Encoding帮助页面上有很多相关信息,我这是相关的:
除了显式设置字符串之外,还有其他方法可以获取声明的编码(并且随着R的演变,这些方式已经改变).函数scan,read.table,readLines和parse有一个用于声明编码的编码参数,iconv声明来自其from参数的编码,并且还声明了在合适的语言环境中的控制台输入.intToUtf8将其输出声明为"UTF-8",如果在合适的语言环境中运行,则标记输出文本连接(请参阅textConnection).在某些情况下(请参阅其帮助页面)source(encoding =)将标记它输出的字符串的编码.
在我看来,基本ASCII字符(字符代码0-127)集中的"unknown"任何内容都会获得编码,"UTF-8"默认情况下,此外的任何字符都将设置为包含扩展ASCII代码(字符代码128-255).