Удаление символов, отличных от ASCII, из файлов данных

У меня есть куча csv файлов, которые я читаю в R и включаю в папку package/data в формате .rdata. К сожалению, не-ASCII-символы в данных не проходят проверку. В пакете tools есть две функции для проверки символов, отличных от ASCII (showNonASCII и showNonASCIIfile), но я не могу найти ни одной, чтобы удалить/очистить их.

Прежде чем я изучу другие инструменты UNIX, было бы здорово сделать все это в R, чтобы я мог поддерживать полный рабочий процесс от необработанных данных до конечного продукта. Существуют ли какие-либо существующие пакеты/функции, которые помогут мне избавиться от символов, отличных от ASCII?


person Maiasaura    schedule 29.03.2012    source источник
comment
Попробуйте использовать регулярные выражения, например функцию gsub. Проверить ?regexp   -  person aatrujillob    schedule 30.03.2012
comment
Вы знаете, что read.csv() принимает аргумент encoding, поэтому вы можете обрабатывать их, по крайней мере, в R? Какая конкретная проверка символов, отличных от ASCII, не выполняется, это в R (если да, опубликуйте его здесь) или во внешнем?   -  person smci    schedule 12.08.2016


Ответы (5)


Чтобы просто удалить символы, отличные от ASCII, вы можете использовать iconv() базы R, установив sub = "". Что-то вроде этого должно работать:

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"

Чтобы найти символы, отличные от ASCII, или узнать, есть ли они вообще в ваших файлах, вы, вероятно, могли бы применить следующие идеи:

## 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
person Josh O'Brien    schedule 29.03.2012

В наши дни несколько лучшим подходом является использование пакета stringi, который предоставляет функцию для общего преобразования Unicode. Это позволяет максимально сохранить исходный текст:

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"
person hadley    schedule 16.05.2016
comment
Любые мысли, как я могу заставить его работать со строками -- iconv("Klinik. der Univ. zu K_ln (AA\u0090R)","latin1","ASCII",sub="") => [1] "Klinik. der Univ. zu K_ln (AAR)" но stringi::stri_trans_general("Klinik. der Univ. zu K_ln (AA\u0090R)", "latin-ascii") => [1] "Klinik. der Univ. zu K_ln (AA\u0090R)" - person xbsd; 13.11.2017
comment
stringi::stri_trans_general(x, "latin-ascii") удаляет некоторые символы, отличные от ASCII, в моем тексте, но не другие. tools::showNonASCII показывает, что неудаленные символы: пробел нулевой ширины, знак товарного знака, знак евро, узкий неразрывный пробел. Означает ли это, что "latin-ascii" является неправильным идентификатором преобразования для моей строки? Есть ли простой способ определить правильный идентификатор преобразования? Спасибо - person Josh; 05.07.2020

Чтобы удалить все слова с не-ascii-символами (заимствованный код у @Hadley), вы можете использовать пакет xfun с filter из dplyr

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

x %>% 
  tibble(name = .) %>%
  filter(xfun::is_ascii(name)== T)
person Nick    schedule 07.05.2019

У меня часто возникают проблемы с iconv, и я фанат base R.

Поэтому вместо того, чтобы удалить юникод или не-ASCII, я использую gsub, используя lapply, чтобы применить его ко всему фрейму данных.

gsub("[^\u0001-\u007F]+|<U\\+\\w+>","", string)

Преимущество этого gsub заключается в том, что он будет соответствовать ряду форматов обозначений. Ниже я показываю отдельные совпадения для двух шаблонов.

x1 <- c("Ekstr\xf8m", "J\xf6reskog", "bi\xdfchen Z\xfcrcher")
gsub("[^\u0001-\u007F]+","", x1)
## "Ekstrm"        "Jreskog"       "bichen Zrcher"
x2 <- c("Ekstr\u00f8m", "J\u00f6reskog", "bi\u00dfchen Z\u00fcrcher")
gsub("[^\u0001-\u007F]+","", x2)
## Same as x1
## "Ekstrm"        "Jreskog"       "bichen Zrcher"
x3 <- c("<U+FDFA>", "1<U+2009>00", "X<U+203E>")
gsub("<U\\+\\w+>","", x3)
## ""    "100" "X"
person katie    schedule 26.01.2021

textclean::replace_non_ascii() сделал всю работу за меня. Эта функция удаляет не только специальные буквы, но и евро, торговые марки и другие символы.

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

 stringi::stri_trans_general(x, "latin-ascii")
    [1] "Ekstrom ★"          "Joreskog €"         "bisschen Zurcher ™"
    
textclean::replace_non_ascii(x)
    [1] "Ekstrom"               "Joreskog"              "bisschen Zurcher cent"
person Yuriy Barvinchenko    schedule 21.03.2021