web-dev-qa-db-fra.com

Forcer le codage du vecteur de caractères de "inconnu" à "UTF-8" dans R

J'ai un problème avec encodage incohérent du vecteur de caractères dans R.

Le fichier texte dans lequel j'ai lu un tableau est codé (via Notepad++) Dans UTF-8 (J'ai également essayé avec UTF-8 without BOM.).

Je veux lire le tableau de ce fichier texte, le convertir en data.table, Définir un key et utiliser la recherche binaire. Lorsque j'ai essayé de le faire, les éléments suivants sont apparus:

Message d'avertissement: dans [.data.table (Poli.dt, "żżonymi", mult = "first"): Un codage connu (latin1 ou UTF-8) a été détecté dans une colonne de jointure. data.table compare les octets actuellement, donc ne prend pas bien en charge les encodages mixtes ; c'est-à-dire, en utilisant à la fois latin1 et UTF-8, ou si des codages inconnus sont non-ascii et certains d'entre eux sont marqués connus et d'autres non. Mais si latin1 ou UTF-8 est utilisé exclusivement et que tous les codages inconnus sont ascii, le résultat devrait être correct. À l'avenir, nous vérifierons pour vous et éviterons cet avertissement si tout va bien. La partie la plus délicate consiste à le faire sans affecter les performances pour les cas ASCII uniquement.

et recherche binaire ne fonctionne pas.

J'ai réalisé que ma colonne data.table -key se compose des deux types de codage: "inconnu" et "UTF-8":

> table(Encoding(poli.dt$Word))
unknown   UTF-8 
2061312 2739122 

J'ai essayé de convertir cette colonne (avant de créer un objet data.table) En utilisant:

  • Encoding(Word) <- "UTF-8"
  • Word<- enc2utf8(Word)

mais sans effet.

J'ai également essayé plusieurs façons de lire un fichier dans R (en définissant tous les paramètres utiles, par exemple encoding = "UTF-8"):

  • data.table::fread
  • utils::read.table
  • base::scan
  • colbycol::cbc.read.table

mais sans effet.

==================================================

Ma version R.:

> R.version
           _                           
platform       x86_64-w64-mingw32          
Arch           x86_64                      
os             mingw32                     
system         x86_64, mingw32             
status                                     
major          3                           
minor          0.3                         
year           2014                        
month          03                          
day            06                          
svn rev        65126                       
language       R                           
version.string R version 3.0.3 (2014-03-06)
nickname       Warm Puppy  

Mes informations de session:

> sessionInfo()
R version 3.0.3 (2014-03-06)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=Polish_Poland.1250  LC_CTYPE=Polish_Poland.1250                LC_MONETARY=Polish_Poland.1250
[4] LC_NUMERIC=C                   LC_TIME=Polish_Poland.1250    

base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] data.table_1.9.2 colbycol_0.8     filehash_2.2-2   rJava_0.9-6     

loaded via a namespace (and not attached):
[1] plyr_1.8.1     Rcpp_0.11.1    reshape2_1.2.2 stringr_0.6.2  tools_3.0.3   
44
Marta Karas

La fonction Encoding renvoie unknown si une chaîne de caractères a une marque "encodage natif" (CP-1250 dans votre cas) ou si elle est en ASCII. Pour faire la distinction entre ces deux cas, appelez:

library(stringi)
stri_enc_mark(poli.dt$Word)

Pour vérifier si chaque chaîne est une séquence d'octets UTF-8 valide, appelez:

all(stri_enc_isutf8(poli.dt$Word))

Si ce n'est pas le cas, votre fichier n'est certainement pas en UTF-8.

Je soupçonne que vous n'avez pas forcé le mode UTF-8 dans la fonction de lecture des données (essayez d'inspecter le contenu de poli.dt$Word pour vérifier cette déclaration). Si ma supposition est vraie, essayez:

read.csv2(file("filename", encoding="UTF-8"))

ou

poli.dt$Word <- stri_encode(poli.dt$Word, "", "UTF-8") # re-mark encodings

Si data.table se plaint toujours des encodages "mixtes", vous pouvez vouloir translittérer les caractères non ASCII, par exemple:

stri_trans_general("Zażółć gęślą jaźń", "Latin-ASCII")
## [1] "Zazolc gesla jazn"
46
gagolews

Je n'ai pas pu trouver moi-même de solution à un problème similaire. Je ne pouvais pas traduire les caractères d'encodage inconnus du fichier txt en quelque chose de plus gérable dans R.

Par conséquent, j'étais dans une situation où le même caractère apparaissait plus d'une fois dans le même ensemble de données, car il était codé différemment ("X" en paramètre latin et "X" en paramètre grec). Cependant, l'opération de sauvegarde txt a conservé cette différence de codage --- bien sûr bien faite.

En essayant certaines des méthodes ci-dessus, rien n'a fonctionné. Le problème est bien décrit "ne peut pas distinguer ASCII de UTF-8 et le bit ne collera pas même si vous le définissez" .

Une bonne solution de contournement est "exporter votre data.frame vers un fichier temporaire CSV et réimporter avec data.table :: fread (), en spécifiant Latin-1 comme encodage source." .

Reproduire/copier l'exemple donné à partir de la source ci-dessus:

package(data.table)
df <- your_data_frame_with_mixed_utf8_or_latin1_and_unknown_str_fields
fwrite(df,"temp.csv")
your_clean_data_table <- fread("temp.csv",encoding = "Latin-1")

J'espère que cela aidera quelqu'un.

6
Elias EstatisticsEU