2016-06-08 16 views
15

== ve %in%'un neden karakter karakterlerine uygulandığında farklı sonuçlar üreteceğini anlamak zor bir zaman geçiriyorum, sadece vektörlerin kodlamasında görünüyor. Bir örnek:== ve%% farklar farklı mı?

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 

Güncelleme:

Bu sonucun göründüğü de platforma bağlıdır. iki ifade döndürür: R 3.3.0 üzerinde

  • TRUE ve FALSE OS X 10.11.5
  • FALSE ve FALSE üzerinde R 3.3.0 Windows 10 (64 bit)
  • TRUE ve TRUE üzerine R 3.2.3 CentOS 7

Bunun bir hata olduğunu düşünmeye başladım.

+1

'% c (a, b) '' de geçerlidir Encoding' bir% -?' Maç, pmatch, UTF-8 charmatch, çoğaltılmış ve benzersiz her maç elemanlarının herhangi olarak işaretlenmiş ise UTF-8.' – rawr

+0

Ve '==' için belgeler, karakterlerin karşılaştırmadan önce UTF-8'e dönüştürüldüğünü söylüyor ... Neden farklı davranıyor olsa da merak ediyorum. – joran

+1

@rawr Eh evet, ama 'a' c (a)' dır, yani aynı zamanda c (a, b) 'de. Ama neden c (a) 'da değil? % '%', değişken ismin aynı olmadığını, sadece değerlerin olduğunu ve değerlerin = = '' '' '' '' '' '' '' '' '' '' '' '' '' döndürdüğü için neden aynı olmadığını anlamıyorum. – RoyalTS

cevap

3

Bu gerçekten bir hatadır ve fixed in 3.3.1 idi.

davranış aslında %in% sol tarafında bir eleman varken sadece FALSE olsun ki, senin örnek gösterir biraz daha daha garip olan:

> a %in% b 
[1] FALSE 
> c(a, a) %in% b 
[1] TRUE TRUE 

yorumlarla ima edildiği gibi %in% sadece match çağırır, böylece sorun da orada görülebilir:

> match(a, b) 
[1] NA 
> match(c(a, a), b) 
[1] 1 1 

önemli argümanları %in% ve matchvardırve table, burada her iki işlev de table'da x arar. Kaputun altında, R unique.c'da tanımlanan match5 işlevinde bunu yapar. Birden fazla x, match5 olması durumunda, hızlı aramaları etkinleştirmek için table bir karma tablo yaratacaktır. Kodu kazarsanız, karşılaştırmanın sequal isimli bir işlevde olduğunu görürsünüz, bu da Seql(STRING_ELT(x, i), STRING_ELT(y, j))'u döndürür (iyi, aslında bundan biraz daha karmaşıktır *). Eğer memory.c yılında Seql bakmak giderseniz Sonra şunları bulacaksınız:

gördüğünüz gibi, UTF-8'e dizeleri dönüştürür,
int result = !strcmp(translateCharUTF8(a), translateCharUTF8(b)); 

.

x sadece bir eleman varsa Ancak, biz sadece x varsa bir kez görmek için table aracılığıyla tarayabilir beri bir karma tablo oluşturma sorun geçmesi saçma. 3.3.0'da, x ve table öğelerinin her biri için eşitliği denetleme kodu Seql kullanmamış ve dizeyi UTF-8'e dönüştürmemiştir. Ancak 3.3.1'den başlayarak, Seql kullanılır, bu nedenle davranış sabittir.

* Dize eşitliği hakkında bir kenara: R aslında dizeleri önbelleğe alacaktır, böylece bir kopya kopyalamak zorunda kalmaz. Yani eğer iki dizgiler aynı yerde ise, eşittirler ve daha fazla kontrol etmeye gerek yoktur!

> .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"