3

Mechanical Turk の data.frame の文字列をサニタイズする既存の関数はありますか? ハングアップしている回線の例を次に示します。

x <- "Duke\U3e32393cs B or C, no concomittant malignancy, ulcerative colitis, Crohn\U3e32393cs disease, renal, heart or liver failure"

これらは Unicode 文字だと思いますが、MT ではそれらを処理できません。私は明らかにこれらを非常に簡単に正規表現できますが、MT をかなり使用しており、すべての非 ASCII 文字を削除するためのより一般的なソリューションを望んでいました。

編集

次のようにエンコーディングを削除できます。

> iconv(x,from="UTF-8",to="latin1",sub=".")
[1] "Duke......s B or C, no concomittant malignancy, ulcerative colitis, Crohn......s disease, renal, heart or liver failure"

しかし、それでもなお、任意の要素に非 utf8 エンコーディングを使用するベクトルに対するより一般的なソリューションが不足しています。

> dput(vec)
c("Colorectal cancer patients Duke\U3e32393cs B or C, no concomittant malignancy, ulcerative colitis, Crohn\U3e32393cs disease, renal, heart or liver failure", 
"Patients with Parkinson\U3e32393cs Disease not already on levodopa", 
"hi")

通常のテキストは「unknown」をエンコードしており、「latin1」への変換がないため、iconv を使用する単純なソリューションは失敗することに注意してください。以下に、より微妙な解決策を 1 つ試みましたが、あまり満足していません。

4

1 に答える 1

4

私自身の質問に答えることに挑戦しようとしていますが、これがすべてのファンキーなテキストを処理できるとは確信していないため、誰かがより良い方法を持っていることを願っています:

sanitize.text <- function(x) {
  stopifnot(is.character(x))
  sanitize.each.element <- function(elem) {
    ifelse(
      Encoding(elem)=="unknown",
      elem,
      iconv(elem,from=as.character(Encoding(elem)),to="latin1",sub="")
    )
  }
  x <- sapply(x, sanitize.each.element)
  names(x) <- NULL
  x
}

> sanitize.text(vec)
[1] "Colorectal cancer patients Dukes B or C, no concomittant malignancy, ulcerative colitis, Crohns disease, renal, heart or liver failure"
[2] "Patients with Parkinsons Disease not already on levodopa"                                                                              
[3] "hi"   

そして、MT のその他のインポートの癖を処理する関数:

library(taRifx)
write.sanitized.csv <- function( x, file="", ... ) {
  sanitize.text <- function(x) {
    stopifnot(is.character(x))
    sanitize.each.element <- function(elem) {
      ifelse(
        Encoding(elem)=="unknown",
        elem,
        iconv(elem,from=as.character(Encoding(elem)),to="latin1",sub="")
      )
    }
    x <- sapply(x, sanitize.each.element)
    names(x) <- NULL
    x
  }
  x <- japply( df=x, sel=sapply(x,is.character), FUN=sanitize.text)
  colnames(x) <- gsub("[^a-zA-Z0-9_]", "_", colnames(x) )
  write.csv( x, file, row.names=FALSE, ... )
}

編集

このコードを配置するのに適した場所がない場合は、文字ベクトルのどの要素が問題を引き起こしているかを突き止め、上記の関数でさえ次のような方法で修正できません。

#' Function to locate a non-ASCII character
#' @param txt A character vector
#' @return A logical of length length(txt) 
locateBadString <- function(txt) {
  vapply(txt, function(x) {
    class( try( substr( x, 1, nchar(x) ) ) )!="try-error"
  }, TRUE )
}

編集2

これはうまくいくはずだと思います

iconv(x, to = "latin1", sub="")

この回答で@Masoudに感謝します:https://stackoverflow.com/a/20250920/636656

于 2012-07-05T14:46:25.857 に答える