Roy*_*lTS 15 r character-encoding
我很难理解为什么==
并且%in%
在应用于依赖于矢量编码时依赖的字符向量时会产生不同的结果.一个例子:
a <- 'Köln'
Encoding(a) <- 'unknown'
Encoding(a)
# [1] "unknown"
b <- a
Encoding(b) <- 'UTF-8'
a == b
# [1] TRUE
a %in% b
# [1] FALSE
Run Code Online (Sandbox Code Playgroud)
更新:
结果似乎也取决于平台.这两个陈述回归:
TRUE
和FALSE
对OS X 10.11.5ř3.3.0FALSE
和FALSE
Windows 10上的R 3.3.0(64位)TRUE
和TRUE
上在CentOS 7 R 3.2.3我开始认为这是一个错误.
这确实是一个bug,并且在3.3.1中修复了。
\n\n这种行为实际上比您的示例所示的更奇怪,因为只有FALSE
当 的左侧有一个元素时,您才会得到%in%
:
> a %in% b\n[1] FALSE\n> c(a, a) %in% b\n[1] TRUE TRUE\n
Run Code Online (Sandbox Code Playgroud)\n\n正如评论所暗示的,%in%
只需调用match
,因此问题也可以在那里看到:
> match(a, b)\n[1] NA\n> match(c(a, a), b)\n[1] 1 1\n
Run Code Online (Sandbox Code Playgroud)\n\n%in%
和 的重要参数match
是x
和table
,其中任一函数搜索x
in table
。在幕后,R 在match5
中定义的函数中执行此操作unique.c
。如果您有多个x
,match5
将创建一个哈希表table
以启用快速查找。如果你深入研究代码,你会发现比较是在一个名为 的函数中完成的sequal
,该函数返回Seql(STRING_ELT(x, i), STRING_ELT(y, j))
(嗯,它实际上比这个复杂一点*)。然后如果你查看Seql
in memory.c
,你会发现:
int result = !strcmp(translateCharUTF8(a), translateCharUTF8(b));\n
Run Code Online (Sandbox Code Playgroud)\n\n正如您所看到的,它将字符串转换为 UTF-8。
\n\n但是,如果x
只有一个元素,那么创建哈希表的麻烦就很愚蠢,因为我们只需扫描table
一次即可查看是否x
存在。在 3.3.0 中,检查x
和 每个元素之间是否相等的代码table
没有使用Seql
,也没有将字符串转换为 UTF-8。但从 3.3.1 开始,Seql
使用了,因此行为是固定的。
* 关于字符串相等性的一点:R 实际上会缓存字符串,这样它就不必存储一堆副本。因此,如果两个字符串位于同一位置,则它们相等,无需进一步检查!
\n\n> .Internal(inspect("K\xc3\xb6ln"))\n@10321b758 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)\n @106831eb8 09 CHARSXP g1c1 [MARK,gp=0x28,ATT] [UTF8] [cached] "K\xc3\xb6ln"\n> .Internal(inspect(b))\n@106831cd8 16 STRSXP g1c1 [MARK,NAM(2)] (len=1, tl=0)\n @106831eb8 09 CHARSXP g1c1 [MARK,gp=0x28,ATT] [UTF8] [cached] "K\xc3\xb6ln"\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
673 次 |
最近记录: |