web-dev-qa-db-fra.com

Suppression de caractères non ASCII des fichiers de données

J'ai un tas de fichiers csv que je lis dans R et que j'inclus dans un dossier package/data dans .rdata format. Malheureusement, les caractères non ASCII dans les données échouent à la vérification. Le package tools a deux fonctions pour vérifier les caractères non ASCII (showNonASCII et showNonASCIIfile) mais je n'arrive pas à en trouver une pour les supprimer/nettoyer.

Avant d'explorer d'autres outils UNIX, ce serait formidable de faire tout cela dans R afin que je puisse maintenir un flux de travail complet des données brutes au produit final. Existe-t-il des packages/fonctions existants pour m'aider à me débarrasser des caractères non ASCII?

68
Maiasaura

Pour simplement supprimer les caractères non ASCII, vous pouvez utiliser la fonction iconv() de base R, en définissant sub = "". Quelque chose comme ça devrait fonctionner:

x <- c("Ekstr\xf8m", "J\xf6reskog", "bi\xdfchen Z\xfcrcher") # e.g. from ?iconv
Encoding(x) <- "latin1"  # (just to make sure)
x
# [1] "Ekstrøm"         "Jöreskog"        "bißchen Zürcher"

iconv(x, "latin1", "ASCII", sub="")
# [1] "Ekstrm"        "Jreskog"       "bichen Zrcher"

Pour localiser caractères non ASCII, ou pour trouver s'il y en avait dans vos fichiers, vous pourriez probablement adapter les idées suivantes:

## Do *any* lines contain non-ASCII characters? 
any(grepl("I_WAS_NOT_ASCII", iconv(x, "latin1", "ASCII", sub="I_WAS_NOT_ASCII")))
[1] TRUE

## Find which lines (e.g. read in by readLines()) contain non-ASCII characters
grep("I_WAS_NOT_ASCII", iconv(x, "latin1", "ASCII", sub="I_WAS_NOT_ASCII"))
[1] 1 2 3
76
Josh O'Brien

De nos jours, une approche légèrement meilleure consiste à utiliser le package stringi qui fournit une fonction pour la conversion unicode générale. Cela vous permet de conserver le texte original autant que possible:

x <- c("Ekstr\u00f8m", "J\u00f6reskog", "bi\u00dfchen Z\u00fcrcher")
x
#> [1] "Ekstrøm"         "Jöreskog"        "bißchen Zürcher"

stringi::stri_trans_general(x, "latin-ascii")
#> [1] "Ekstrom"          "Joreskog"         "bisschen Zurcher"
72
hadley

Pour supprimer tous les mots avec des caractères non ascii (empruntant du code à @Hadley), vous pouvez utiliser le package xfun avec filter de dplyr

x <- c("Ekstr\u00f8m", "J\u00f6reskog", "bi\u00dfchen Z\u00fcrcher", "alex")
x

x %>% 
  tibble(name = .) %>%
  filter(xfun::is_ascii(name)== T)
0
Nick