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