9

这个问题源于以下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ø"

请注意,尽管identical认为两者相同,但底层字符串缓存将“hø”存储在两个不同的位置,而将“a”存储在一个位置。怎么了?这是一个 R 字符串缓存错误吗?

这很重要的原因是%chin%在这里失败(由于上述差异):

library(data.table)
"a" %chin% names(df)
#[1] TRUE
"hø" %chin% names(df)
#[1] FALSE
4

1 回答 1

8

"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

Encoding帮助页面上有很多相关信息,我这将是相关的:

除了显式设置之外,字符串还有其他方法来获取声明的编码(这些方法随着 R 的发展而变化)。函数 scan、read.table、readLines 和 parse 有一个用于声明编码的 encoding 参数,iconv 从其 from 参数声明编码,并且还声明了合适语言环境中的控制台输入。intToUtf8 将其输出声明为“UTF-8”,并且如果在合适的语言环境中运行,则标记输出文本连接(请参阅 textConnection)。在某些情况下(参见其帮助页面) source(encoding=) 将标记它输出的字符串的编码。

更新

在我看来,基本 ASCII 字符(字符代码 0-127)集中的任何内容都会获得"unknown"编码,并且默认情况下会设置此之外的任何字符"UTF-8",包括扩展 ASCII 代码(字符代码 128-255)。

于 2013-10-08T21:02:40.230 回答