【问题标题】:Sanitize text for Mechanical Turk?为 Mechanical Turk 清理文本?
【发布时间】:2012-07-05 13:20:26
【问题描述】:

是否有一个预先存在的功能可以为 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 编码的 any 元素的向量缺乏更通用的解决方案。

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

请注意,常规文本编码“未知”,它没有转换为“latin1”,所以使用 iconv 的简单解决方案失败。我在下面尝试了一种更细微的解决方案,但我对此不太满意。

【问题讨论】:

  • 在测试对象上提供 dput() 不是更好吗?然后将附加属性。
  • @Dwin 那是dput()的输出。然后我将其复制/粘贴回 R 以检查是否保留了 UTF-8 编码。
  • 您希望iconv(x, "UTF-8", "ASCII", ".") 的哪一部分更通用?你的意思是你想要一些能检测当前编码的东西,以防它不是 UTF-8 或 ASCII 吗?
  • @JoshO'Brien 没错。见下文。

标签: r mechanicalturk


【解决方案1】:

尝试回答我自己的问题,希望有人有更好的方法,因为我不相信这会处理所有时髦的文本:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多