2014-04-18 18 views
6

Ich habe eine Datenbank mit den Namen der Premiership Fußballer, die ich in R (3.02) lese, aber ich stoße auf Schwierigkeiten, wenn es um Spieler mit fremden Zeichen im Namen geht (Umlaute, Akzente etc.). Der folgende Code veranschaulicht dies:Lesen von fremden Zeichen

PlayerData<-read.table("C:\\Users\\Documents\\Players.csv",quote=NULL, dec = ".",,sep=",", stringsAsFactors=F,header=T,fill=T,blank.lines.skip = TRUE) 
Test<-PlayerData[c(33655:33656),] #names of the players here are "Cazorla" "Özil" 

Test[Test$Player=="Cazorla",] #Outputs correct details 
Test[Test$Player=="Ozil",] # Can not find data '0 rows> (or 0-length row.names)' 
< 

#Example of how the foreign character is treated: 
substr("Özil",1,1) 
[1] "Ã" 
substr("Özil",1,2) 
[1] "Ö" 
substr("Özil",2,2) 
[1] " 
substr("Özil",2,3) 
[1] "z 

Ich habe versucht, die Zeichen zu ersetzen, wie es hier beschrieben: R: Replacing foreign characters in a string, aber da die Zeichen mit Akzent in meinem Beispiel erscheinen als zwei seperate zu lesenden Zeichen Ich glaube nicht, es funktioniert.

Ich wäre dankbar für Vorschläge oder Problemumgehungen.

Die Datei steht zum Download zur Verfügung here.

+0

Konnten Sie die zwei Zeilen Ihrer CSV irgendwo im Netz setzen? Vielleicht kann 'iconv' helfen. –

+1

Dies erfordert eine viel längere Antwort (die meisten außerhalb meiner Expertise), aber versuchen Sie alles in UTF-8 zu konvertieren: 'Test $ Player <- iconv (Test $ Player, zu = 'UTF-8')'. Überprüfen Sie, ob die Indizierung wie erwartet funktioniert. Wenn Sie keine Kodierung erzwingen, werden Zeichenketten abhängig von Ihrem Systemgebietsschema interpretiert (die von Ihnen angegebenen Beispiele funktionierten wie erwartet auf meinem System). – ilir

Antwort

3

BEARBEITEN: Es scheint, dass die von Ihnen bereitgestellte Datei eine andere Kodierung als die Ihres Systems verwendet.

An (experimentell) Codierung Erfassung durch die stri_enc_detect Funktion aus dem stringi Paket getan gibt:

library('stringi') 
PlayerDataRaw <- stri_read_raw('~/Desktop/PLAYERS.csv') 
stri_enc_detect(PlayerDataRaw) 
## [[1]] 
## [[1]]$Encoding 
## [1] "ISO-8859-1" "ISO-8859-2" "ISO-8859-9" "IBM424_rtl" 
## 
## [[1]]$Language 
## [1] "en" "ro" "tr" "he" 
## 
## [[1]]$Confidence 
## [1] 0.25 0.14 0.09 0.02 

So höchstwahrscheinlich die Datei in ISO-8859-1 auch bekannt als latin1 ist. Glücklicherweise muss R die Eingabe beim Lesen dieser Datei nicht neu codieren - es kann nur eine andere als die Standardcodierung (== native) festlegen. Sie können die Datei laden mit:

Jetzt können Sie einzelne Zeichen korrekt zugreifen, z. mit der stri_sub Funktion:

Test<-PlayerData[c(33655:33656),] 
Test 
##   T   Away H.A Home Player Year 
## 33655 33654 CrystalPalace 1 Arsenal Cazorla 2013 
## 33656 33655 CrystalPalace 1 Arsenal Özil 2013 

stri_sub(Test$Player, 1, length=1) 
## [1] "C" "Ö" 
stri_sub(Test$Player, 2, length=1) 
## [1] "a" "z" 

Wie pro Strings zu vergleichen, hier sind die Ergebnisse für einen Test für die Gleichstellung von Strings, mit Akzent Zeichen „abgeflacht“:

stri_cmp_eq("Özil", "Ozil", stri_opts_collator(strength=1)) 
## [1] TRUE 

Sie auch von Akzent loswerden kann Zeichen mit dem Transliterator iconv (ich bin nicht sicher, ob es unter Windows verfügbar ist).

iconv(Test$Player, 'latin1', 'ASCII//TRANSLIT') 
## [1] "Cazorla" "Ozil" 

Oder mit einem sehr leistungsfähigen Transliterator von stringi Paket (stringi Version> = 0,2-2):

stri_trans_general(Test$Player, 'Latin-ASCII') 
## [1] "Cazorla" "Ozil" 
+0

Große Antwort - Die Transliterator-Funktion 'iconv' funktioniert fantastisch, um das zu sortieren. – Pash101

0

Vielen Dank an alle mit diesem für Ihre Hilfe.

Die Zeichenfolgen wurden korrekt als UTF-8 codiert (ich fügte das Argument sowie iconv hinzu, wie vorgeschlagen). Dies schien nicht das Problem zu sein.

Ich habe auch die stri_sub() Funktion verwendet. aber das schien auch nicht zu funktionieren (es behandelte auch den Akzent als ein separates Zeichen stri_sub("Özil",1,3) = "Ã<U+0096>z").

aber danke für mich in Richtung der stringi Dokumentation zeigt, gab es mir die Idee für dieses Problem zu umgehen, die ich bin zu verwenden glücklich:

remove.accents<-function(s){ 
oldrefs<-c(214,225)#Ö, á 
newrefs<-c(79,97)#O,a 

New<-utf8ToInt(s) 
for(i in 1:length(oldrefs)){ 
New<-as.numeric(gsub(oldrefs[i],newrefs[i],New)) 
NEW<-intToUtf8(New) 
} 
NEW 
} 
> (remove.accents("Özil")) 
[1] "Ozil" 
> (remove.accents("Suárez")) 
[1] "Suarez" 

ich jetzt den oldrefs/newref Arrays füllen kann Bei den Int-Referenzen für die anderen Charaktere brauche ich für bestimmte Spieler (Touré Jääskeläinen, Agüero etc.) was hoffentlich nicht zu lange dauern dürfte!

+0

Vielen Dank für das Aufzeigen dieser interessanten Aufgabe zur Verarbeitung von Strings. Ich werde bald damit beginnen, automatische Transliterationsmechanismen in Stringi zu integrieren, siehe [diese Ausgabe] (https://github.com/Rexamine/stringi/issues/72) – gagolews

+0

If ' stri_sub' hat nicht richtig funktioniert, ich bin mir sicher, dass deine Daten nicht richtig gelesen wurden. Was ist das Ergebnis des Aufrufs von 'Encoding (Test $ Player)'? – gagolews

+0

Ich habe vor dem Import das 'encoding = 'UTF-8''-Argument in' read.table' eingefügt. 'Encoding (Test $ Player)' gibt mir jetzt diese Ausgabe: '" unknown "" UTF-8 "' (unbekannt ist in diesem Fall Cazorla; UTF-8, der zweite Spieler, ist Özil). Wenn UTF-8 übergeben wird, bedeutet dies, dass Özil nun als ' zil' – Pash101

Verwandte Themen