Es ist in der Tat ein Fehler, und es war fixed in 3.3.1.
Das Verhalten ist eigentlich ein bisschen seltsamer als Ihr Beispiel zeigt, dass Sie nur FALSE
erhalten, wenn Sie ein Element auf der linken Seite von %in%
haben:
> a %in% b
[1] FALSE
> c(a, a) %in% b
[1] TRUE TRUE
Wie die Kommentare impliziert, %in%
nur Anrufe match
, so kann das Problem auch dort zu sehen:
> match(a, b)
[1] NA
> match(c(a, a), b)
[1] 1 1
die wichtigen Argumente %in%
und match
sind x
und table
, wobei jede Funktion nach x
in table
sucht. Unter der Haube macht R dies in der match5
-Funktion, die in unique.c
definiert ist. Für den Fall, dass Sie mehr als eine x
haben, wird match5
eine Hash-Tabelle aus table
erstellen, um schnelle Suchvorgänge zu ermöglichen. Wenn Sie den Code durchforsten, werden Sie sehen, dass der Vergleich in einer Funktion namens sequal
erfolgt, die Seql(STRING_ELT(x, i), STRING_ELT(y, j))
zurückgibt (nun, es ist tatsächlich ein bisschen komplexer als das *). Dann, wenn man sich Seql
in memory.c
suchen gehen, werden Sie finden:
int result = !strcmp(translateCharUTF8(a), translateCharUTF8(b));
, die, wie Sie sehen können, die Strings in UTF-8 konvertiert.
Wenn jedoch x
nur ein Element hat, es ist dumm durch die Mühe zu gehen, um eine Hash-Tabelle zu erstellen, da wir nur durch table
einmal scannen können, um zu sehen, ob x
ist. In 3.3.0 hat der Code, der auf Gleichheit zwischen x
und jedem Element von table
überprüft wurde, Seql
nicht verwendet und die Zeichenfolge nicht in UTF-8 konvertiert. Aber ab 3.3.1 wird Seql
verwendet, also ist das Verhalten festgelegt.
* Ein wenig beiseite bei String-Gleichheit: R wird tatsächlich Strings Cache, so dass es nicht eine Reihe von Kopien speichern muss. Wenn also zwei Strings am gleichen Ort sind, sind sie gleich und es ist nicht nötig, weiter zu suchen!
> .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"
'a% in% c (a, b)' gilt 'Encoding' -' Spiel, pmatch, charmatch, vervielfältigt und einzigartige Spiel in UTF-8, wenn eine der Elemente sind markiert als UTF-8.' – rawr
Und die Dokumentation für '==' sagt, dass alle Zeichen vor dem Vergleich in UTF-8 konvertiert werden ... Ich wäre neugierig, warum das unterschiedliche Verhalten obwohl. – joran
@raw Nun ja, aber 'a' steht in' c (a) 'so ist es auch in' c (a, b) '. Aber warum ist 'b' nicht in' c (a) '? '% in%' überprüft nicht, ob der Variablenname identisch ist, nur Werte und ich verstehe nicht, warum die Werte nicht identisch sind, da '==' 'TRUE' zurückgibt. – RoyalTS