這確實是一個錯誤,它是fixed in 3.3.1。
的行爲實際上是一個有點古怪比你的例子表明,在你只能得到FALSE
當你有上%in%
的左側一個元素:
> a %in% b
[1] FALSE
> c(a, a) %in% b
[1] TRUE TRUE
由於暗示的意見,%in%
只是調用match
,所以這個問題可以在那裏看到了太多:
> match(a, b)
[1] NA
> match(c(a, a), b)
[1] 1 1
的重要參數%in%
和match
是x
和table
,其中任一函數都在table
中搜索x
。在引擎蓋下,R在unique.c
中定義的match5
函數中執行此操作。如果您有多個x
,match5
將從table
創建一個哈希表以啓用快速查找。如果你仔細查看代碼,你會發現比較是在一個名爲sequal
的函數中完成的,該函數返回Seql(STRING_ELT(x, i), STRING_ELT(y, j))
(好吧,實際上它比這個*更復雜一點)。然後,如果你去看看Seql
在memory.c
,你會發現:
int result = !strcmp(translateCharUTF8(a), translateCharUTF8(b));
其中,你可以看到,轉換字符串UTF-8。
然而,如果x
只有一個元素,這是愚蠢的去完成創建一個哈希表的麻煩,因爲我們可以只通過掃描一次table
,看是否x
是存在的。在3.3.0中,檢查x
與table
的每個元素之間是否相等的代碼未使用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)'爲真'Encoding'一個% - ?'的比賽,pmatch,charmatch,複製和獨特的所有匹配以UTF-8如果任何元素被標記爲UTF-8「。 – rawr
== =='的文檔說在比較之前字符都轉換爲UTF-8 ...我會好奇爲什麼不同的行爲。 – joran
@rawr嗯,但'a'在'c(a)'中,所以它也在'c(a,b)'中。但爲什麼'c(a)'中不是'b'? '%in%'不檢查變量名是否相同,只有值,我不明白爲什麼這些值不相同,因爲'=='返回'TRUE'。 – RoyalTS