Đó thực sự là lỗi và là fixed in 3.3.1.
Các hành vi thực sự là kì quặc một chút so với ví dụ của bạn chỉ ra, trong đó bạn chỉ nhận được FALSE
khi bạn có một yếu tố ở phía bên trái của %in%
:
> a %in% b
[1] FALSE
> c(a, a) %in% b
[1] TRUE TRUE
Như ngụ ý của ý kiến, %in%
chỉ cần gọi match
, vì vậy vấn đề có thể được nhìn thấy có quá:
> match(a, b)
[1] NA
> match(c(a, a), b)
[1] 1 1
những lập luận quan trọng đối với %in%
và match
là x
và table
, trong đó một trong hai chức năng tìm kiếm x
trong table
. Dưới mui xe, R thực hiện điều này trong hàm match5
được xác định trong unique.c
. Trong trường hợp bạn có nhiều hơn một x
, match5
sẽ tạo bảng băm từ table
để bật tra cứu nhanh. Nếu bạn khai thác mã, bạn sẽ thấy rằng việc so sánh được thực hiện trong một hàm có tên là sequal
, trả về Seql(STRING_ELT(x, i), STRING_ELT(y, j))
(tốt, nó thực sự phức tạp hơn một chút so với điều này *). Sau đó, nếu bạn đi nhìn vào Seql
trong memory.c
, bạn sẽ tìm thấy:
int result = !strcmp(translateCharUTF8(a), translateCharUTF8(b));
nào, như bạn có thể thấy, chuyển đổi chuỗi sang UTF-8.
Tuy nhiên, nếu x
chỉ có một yếu tố, đó là ngớ ngẩn phải đi qua những rắc rối của việc tạo ra một bảng băm, vì chúng ta chỉ có thể quét qua table
một lần để xem nếu x
là ở đó. Trong 3.3.0, mã để kiểm tra sự bình đẳng giữa x
và mỗi phần tử của table
không sử dụng Seql
và không chuyển đổi chuỗi thành UTF-8. Nhưng bắt đầu từ 3.3.1, Seql
được sử dụng, do đó hành vi được khắc phục.
* Một chút sang một bên trên chuỗi bình đẳng: R sẽ thực sự lưu trữ các chuỗi để nó không phải lưu trữ một loạt các bản sao. Vì vậy, nếu hai chuỗi ở cùng một vị trí, chúng bằng nhau và không cần kiểm tra thêm nữa!
> .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% trong% c (a, b)' là true '? Encoding' -' match, pmatch, charmatch, trùng lặp và duy nhất tất cả khớp trong UTF-8 nếu bất kỳ phần tử nào được đánh dấu là UTF-8.' – rawr
Và tài liệu cho '==' nói rằng các ký tự đều được chuyển đổi thành UTF-8 trước khi so sánh ... Tôi sẽ tò mò tại sao lại có hành vi khác. – joran
@rawr Vâng vâng, nhưng 'a' nằm trong' c (a) 'vì vậy nó cũng trong' c (a, b) '. Nhưng tại sao không phải là 'b' trong' c (a) '? '% in%' không kiểm tra tên biến là giống hệt nhau, chỉ có giá trị và tôi không hiểu tại sao các giá trị không giống nhau khi '==' trả về 'TRUE'. – RoyalTS