Si tratta in effetti di un bug ed era fixed in 3.3.1.
Il comportamento è in realtà un po 'più strano che il vostro esempio indica, in che si ottiene solo FALSE
quando si dispone di un elemento sul lato sinistro della %in%
:
> a %in% b
[1] FALSE
> c(a, a) %in% b
[1] TRUE TRUE
Come implicita dai commenti, %in%
solo chiamate match
, in modo che il problema può essere visto anche lì:
> match(a, b)
[1] NA
> match(c(a, a), b)
[1] 1 1
Gli argomenti importanti da %in%
e match
sono x
e table
, in cui una delle funzioni cerca x
in table
. Sotto il cofano, R lo fa nella funzione match5
definita in unique.c
. Nel caso in cui si disponga di più di uno x
, match5
creerà una tabella hash da table
per abilitare ricerche veloci. Se si scava il codice, si vedrà che il confronto viene eseguito in una funzione denominata sequal
, che restituisce Seql(STRING_ELT(x, i), STRING_ELT(y, j))
(beh, in realtà è un po 'più complesso di questo *). Poi se si va a guardare Seql
in memory.c
, troverete:
int result = !strcmp(translateCharUTF8(a), translateCharUTF8(b));
Il che, come si può vedere, converte le stringhe in UTF-8.
Tuttavia, se x
ha un solo elemento, è stupido per passare attraverso la briga di creare una tabella di hash, dal momento che possiamo solo eseguire la scansione attraverso table
una volta per vedere se x
c'è. In 3.3.0, il codice per verificare l'uguaglianza tra x
e ogni elemento di table
non ha utilizzato Seql
e non ha convertito la stringa in UTF-8. Ma a partire dal 3.3.1, viene utilizzato Seql
, quindi il comportamento è corretto.
* Un po 'da parte sull'equità delle stringhe: R memorizzerà effettivamente le stringhe in modo che non debba memorizzare un gruppo di copie. Quindi se due stringhe si trovano nella stessa posizione, sono uguali e non è necessario controllare ulteriormente!
> .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"
'una% in% c (a, b)' 'è vero Encoding' -?' Match, pmatch, charmatch, duplicato e unico tutti i match in UTF-8 se uno qualsiasi degli elementi sono contrassegnati come UTF-8.' – rawr
E la documentazione di '==' dice che i caratteri sono tutti convertiti in UTF-8 prima del confronto ... Sarei curioso del perché il diverso comportamento però. – joran
@rawr Beh, sì, ma 'a' è in' c (a) 'quindi è anche in' c (a, b) '. Ma perché non è 'b' in' c (a) '? '% in%' non controlla che il nome della variabile sia identico, solo valori e non capisco perché i valori non siano identici dato che '==' restituisce 'TRUE'. – RoyalTS