R ==和%在%中根据字符编码不同?
我很难理解为什么%中的R ==和%在%中根据字符编码不同?,r,character-encoding,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 a这确实是一个bug,而且确实是 该行为实际上比您的示例显示的更为奇怪,因为只有当%中%的左侧有一个元素时
==
和%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
a这确实是一个bug,而且确实是
该行为实际上比您的示例显示的更为奇怪,因为只有当%
中%的左侧有一个元素时,才会得到FALSE
:
> a %in% b
[1] FALSE
> c(a, a) %in% b
[1] TRUE TRUE
正如注释所暗示的,%
中的%只调用match
,因此问题也可以在那里看到:
> match(a, b)
[1] NA
> match(c(a, a), b)
[1] 1 1
%
和match
中%的重要参数是x
和table
,其中任一函数在table
中搜索x
。在发动机罩下,R在unique.c
中定义的match5
功能中执行此操作。如果您有多个x
,match5
将从表
创建一个哈希表,以启用快速查找。如果你仔细研究代码,你会发现比较是在一个名为sequal
的函数中完成的,该函数返回Seql(STRING_ELT(x,i),STRING_ELT(y,j))
(实际上,它比这个函数复杂一点)。然后,如果您查看memory.c
中的Seql
,您会发现:
int result = !strcmp(translateCharUTF8(a), translateCharUTF8(b));
如您所见,它将字符串转换为UTF-8
然而,如果x
只有一个元素,那么创建一个哈希表是很愚蠢的,因为我们可以只扫描table
一次,看看x
是否存在。在3.3.0中,用于检查x
和表的每个元素之间是否相等的代码没有使用Seql
,也没有将字符串转换为UTF-8。但是从3.3.1开始,使用了Seql
,因此行为是固定的
*关于字符串相等性的一点旁白是:R实际上会缓存字符串,这样它就不必存储一堆副本。因此,如果两个字符串位于同一位置,则它们相等,无需进一步检查
> .Internal(inspect("Köln"))
@10321b758 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)
@106831eb8 09 CHARSXP g1c1 [MARK,gp=0x28,ATT] [UTF8] [cached] "Köln"
> .Internal(inspect(b))
@106831cd8 16 STRSXP g1c1 [MARK,NAM(2)] (len=1, tl=0)
@106831eb8 09 CHARSXP g1c1 [MARK,gp=0x28,ATT] [UTF8] [cached] "Köln"
%c(a,b)
中的a%为真?编码--匹配,pmatch,charmatch,如果有任何元素被标记为UTF-8,则重复且唯一的所有元素在UTF-8中都匹配。
和=
的文档中说,在比较之前,字符都转换为UTF-8……我很好奇为什么会有不同的行为。@rawr是的,但是a
在c(a)
中,所以它也在c(a,b)
中。但是为什么b
不在c(a)
中呢<%
中的code>%不检查变量名是否相同,只检查值,我不理解为什么值不相同,因为=
返回TRUE
。match
的文档说“如果任何输入标记为“bytes”,字符串将作为字节序列进行比较。”。未知
是字节序列吗。。。在我的Cygwin 3.1.3安装中,两个测试的结果都是TRUE
,但在我的RStudio 3.2.1安装中,两个测试的结果都是FALSE
。而你(OP)似乎得到了一种混合物。没有什么是有意义的。。。没有什么是有意义的。。。