Nicht-ASCII-Zeichen aus Datendateien entfernen

74

Ich habe eine Reihe von csvDateien, die ich in R einlese und die in einem Paket- / Datenordner im .rdataFormat enthalten sind. Leider bestehen die Nicht-ASCII-Zeichen in den Daten die Prüfung nicht. Das toolsPaket hat zwei Funktionen, um nach Nicht-ASCII-Zeichen ( showNonASCIIund showNonASCIIfile) zu suchen, aber ich kann anscheinend keine finden, um sie zu entfernen / zu bereinigen.

Bevor ich mich mit anderen UNIX-Tools befasse, wäre es großartig, dies alles in R zu tun, damit ich einen vollständigen Workflow von den Rohdaten bis zum Endprodukt aufrechterhalten kann. Gibt es vorhandene Pakete / Funktionen, mit denen ich die Nicht-ASCII-Zeichen entfernen kann?

Maiasaura
quelle
Versuchen Sie es mit regulären Ausdrücken, zum Beispiel der Funktion gsub. Überprüfen Sie? Regexp
aatrujillob
Sie wissen, dass dies read.csv()ein encodingArgument erfordert, sodass Sie damit umgehen können, zumindest in R? Welche spezifische Prüfung schlagen die Nicht-ASCII-Zeichen fehl, ist sie in R (wenn ja, hier posten) oder extern?
smci

Antworten:

81

Um die Nicht-ASCII-Zeichen einfach zu entfernen , können Sie die iconv()Einstellung Basis-R verwenden sub = "". So etwas sollte funktionieren:

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"

Um lokalisieren Nicht-ASCII - Zeichen, oder zu finden , wenn es in Ihren Dateien überhaupt war, könnten Sie die folgenden Ideen wahrscheinlich anpassen:

## 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
Josh O'Brien
quelle
79

Heutzutage ist es etwas besser, das Stringi-Paket zu verwenden, das eine Funktion für die allgemeine Unicode-Konvertierung bietet. Auf diese Weise können Sie den Originaltext so weit wie möglich beibehalten:

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"
Hadley
quelle
1
Irgendwelche Gedanken, wie ich es mit stringi - iconv("Klinik. der Univ. zu K_ln (AA\u0090R)","latin1","ASCII",sub="") => [1] "Klinik. der Univ. zu K_ln (AAR)"butstringi::stri_trans_general("Klinik. der Univ. zu K_ln (AA\u0090R)", "latin-ascii") => [1] "Klinik. der Univ. zu K_ln (AA\u0090R)"
xbsd
stringi::stri_trans_general(x, "latin-ascii")Entfernt einige der Nicht-ASCII-Zeichen in meinem Text, andere jedoch nicht. tools::showNonASCIIDie nicht entfernten Zeichen sind: Leerzeichen mit der Breite Null, Markenzeichen, Eurozeichen, schmales Leerzeichen. Bedeutet dies, dass "latin-ascii"die falsche Transformationskennung für meine Zeichenfolge ist? Gibt es eine einfache Möglichkeit, die richtige Transformationskennung herauszufinden? Danke
Josh
2

Um alle Wörter mit Nicht-ASCII-Zeichen zu entfernen (Code von @Hadley ausleihen), können Sie das Paket xfunmit filterfrom verwendendplyr

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

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