【问题标题】:How to read \" double-quote escaped values with read.table in R如何在 R 中使用 read.table 读取 \" 双引号转义值
【发布时间】:2011-10-27 08:33:14
【问题描述】:

我无法读取包含如下行的文件。

"_:b5507F4C7x59005","Fabiana D\"atri"

有什么想法吗?如何让 read.table 明白 \" 是引号的转义?

干杯, 亚历山大

【问题讨论】:

标签: r csv escaping double-quotes


【解决方案1】:

在我看来,read.table/read.csv 无法处理转义引号。

...但我认为我有一个受@nullglob 启发的(丑陋的)变通方法;

  • 首先读取不带引号字符的文件。 (正如@Ben Bolker 所说,这不会处理嵌入式,
  • 然后遍历字符串列并删除引号:

测试文件看起来像这样(我添加了一个非字符串列来衡量):

13,"foo","Fab D\"atri","bar"
21,"foo2","Fab D\"atri2","bar2"

这里是代码:

# Generate test file
writeLines(c("13,\"foo\",\"Fab D\\\"atri\",\"bar\"",
             "21,\"foo2\",\"Fab D\\\"atri2\",\"bar2\"" ), "foo.txt")

# Read ignoring quotes
tbl <- read.table("foo.txt", as.is=TRUE, quote='', sep=',', header=FALSE, row.names=NULL)

# Go through and cleanup    
for (i in seq_len(NCOL(tbl))) {
    if (is.character(tbl[[i]])) {
        x <- tbl[[i]]
        x <- substr(x, 2, nchar(x)-1) # Remove surrounding quotes
        tbl[[i]] <- gsub('\\\\"', '"', x) # Unescape quotes
    }
}

那么输出是正确的:

> tbl
  V1   V2          V3   V4
1 13  foo  Fab D"atri  bar
2 21 foo2 Fab D"atri2 bar2

【讨论】:

  • 在我看来,工作量比预期的要多。但是@Tommy 解决方案有效!谢谢!
【解决方案2】:

在 Linux/Unix 上(或在带有 cygwin 或 GnuWin32 的 Windows 上),您可以使用 sed 将转义的双引号 \" 转换为双引号 ""read.csv 可以很好地处理:

p <- pipe(paste0('sed \'s/\\\\"/""/g\' "', FILENAME, '"'))
d <- read.csv(p, ...)
rm(p)

实际上,以下sed 命令用于预处理 CSV 输入:

sed 's/\\"/""/g' file.csv

我不认为这很漂亮,但至少你不必离开 R 环境......

【讨论】:

    【解决方案3】:

    我提前道歉,这不是更详细 - 我正处于代码紧缩的中间。

    您可以考虑使用 scan() 函数。我创建了一个简单的示例文件“sample.csv”,其中包括:

    V1,V2
    "_:b5507F4C7x59005","Fabiana D\"atri"
    

    两种快速的可能性是(带有注释的输出,以便您可以复制粘贴到命令行):

    test <- scan("sample.csv", sep=",", what='character',allowEscapes=TRUE)
    ## Read 4 items
    test
    ##[1] "V1"                "V2"                "_:b5507F4C7x59005"
    ##[4] "Fabiana D\\atri\n"
    

    test <- scan("sample.csv", sep=",", what='character',comment.char="\\")
    ## Read 4 items
    test
    ## [1] "V1"                "V2"                "_:b5507F4C7x59005"
    ## [4] "Fabiana D\\atri\n"
    

    您可能需要多玩一点才能得到想要的东西。我看到你已经提到了 writeLines,所以你可能已经尝试过这个。不管怎样,祝你好运!

    【讨论】:

    • allowEscapes 也是read.csvread.table 的参数
    【解决方案4】:

    我能够通过设置 quote 参数让您的示例工作:

    > read.csv('test.csv',quote="'",head=FALSE)
                       V1                  V2
    1 "_:b5507F4C7x59005" "Fabiana D\\"atri" 
    2 "_:b5507F4C7x59005" "Fabiana D\\"atri" 
    

    【讨论】:

    • 我认为添加 allowEscapes=TRUE 可能会有所帮助,但似乎没有。
    • ...除非文件中有单引号,否则这种方法有效。但是所有字符串都以双引号结束(并且转义的引号仍然被转义),因此需要进行更多处理...
    • 正如@Ben 发布的那样,解决方案不适用于我。我在其他字段中有逗号。
    【解决方案5】:

    read_delim 来自包 readr 可以使用参数escape_doubleescape_backslash 处理转义和双引号。

    例如,如果我们的文件通过加倍引号来转义:

    "quote""","hello"
    1,2
    

    然后我们使用

    read_delim(file, delim=',')  # default escape_backslash=FALSE, escape_double=TRUE
    

    如果我们的文件用反斜杠转义引号:

    "quote\"","hello"
    1,2
    

    我们使用

    read_delim(file, delim=',', escape_double=FALSE, escape_backslash=TRUE)
    

    【讨论】:

      【解决方案6】:

      read.csv() 应该没问题。查看?read.csv 的帮助 - 指定报价的选项是quote = "...."。不过,在这种情况下,可能会出现问题:read.csv() 似乎更喜欢看到匹配的引号。

      我对@9​​87654325@ 进行了同样的尝试,在sample.txt 中添加了您的文本,它似乎有效。当read.csv() 一切都失败时,我倾向于备份到read.table() 并仔细指定参数。

      【讨论】:

      • 不行,不行,试试稍微复杂一点的,比如:writeLines(c("\"foo\",\"Fab D\\\"atri\",\"bar2\"","\"foo2\",\"Fab D\\\"atri2\",\"bar2\"" ), "foo.txt")...
      • 请记住,从 R 的角度来看,您的原始输出是每行只有 1 个字符串,而不是一堆单独引用的字符串。如果您想在文件中引用整个内容,则需要使用引号。
      • read.table 之后,我得到a$V2 输出[1] ",\"Fab" ",\"Fab" 这是不正确的。 ...如果您在文本编辑器中打开“foo.txt”,您会看到它包含像 OP 所述的字符串。
      猜你喜欢
      • 1970-01-01
      • 2011-06-09
      • 2011-04-19
      • 2018-01-17
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多