【问题标题】:Read CSV file with embedded double quotes and commas读取带有嵌入双引号和逗号的 CSV 文件
【发布时间】:2019-03-28 04:30:18
【问题描述】:

我正在尝试使用 data.table 包中的 fread() 函数读取脏 CSV 文件,但在字符串值中嵌入双引号和逗号存在问题,即引号字段中存在未转义的双引号.以下示例数据说明了我的问题。它由 3 行/行和 6 列组成,第一行包含列名:

"SA","SU","CC","CN","POC","PAC"
"NE","R","000","H "B", O","1","8"
"A","A","000","P","E,5","8"

第一个问题在第 2 行,其中嵌入了一对双引号和一个逗号:"H "B", O"。第二个问题在第 3 行,双引号中有一个逗号:"E,5"。我尝试了以下方法:

尝试 1

library(data.table)
x1 <- fread(file = "example.csv", quote = "\"")

输出:

> x1
     V1 "SA" "SU"   "CC" "CN" "POC" "PAC"
1: "NE"  "R"    0 "H "B"   O"   "1"     8
2:  "A"  "A"    0    "P"   "E    5"     8

留言:

在前 100 行中发现并解决了不正确的引用。如果字段 没有被引用(例如,字段分隔符没有出现在任何 字段),请尝试使用 quote="" 来避免此警告。检测到 6 个列名,但 数据有 7 列(即无效文件)。添加了 1 个额外的默认值 被猜测为行名的第一列的列名或 一个索引。如果这个猜测不正确,之后使用 setnames(),或者 修复创建文件的文件写入命令以创建有效的 文件。

结论:结果不正确,因为它添加了一个新列V1

尝试 2

x2 <- fread(file = "example.csv", quote = "")

输出:

> x2
     V1 "SA"  "SU"   "CC" "CN" "POC" "PAC"
1: "NE"  "R" "000" "H "B"   O"   "1"   "8"
2:  "A"  "A" "000"    "P"   "E    5"   "8"

消息:

检测到 6 个列名,但数据有 7 个列(即无效 文件)。为第一列添加了 1 个额外的默认列名,即 猜测是行名或索引。如果这之后使用 setnames() 猜测不正确,或者修复创建 文件来创建一个有效的文件。

结论:结果不正确,因为它增加了一个新列V1..

解决方案?

我正在寻找的是一种获得类似于

的输出的方法
> x3
   SA SU CC       CN POC PAC
1: NE  R  0 H 'B', O   1   8
2:  A  A  0        P E,5   8

最好使用 fread(),但也欢迎其他建议。

【问题讨论】:

    标签: r csv data.table


    【解决方案1】:

    您可以尝试事先清理数据并将双引号替换为单引号。

    x = readLines('my_file.csv')
    y = gsub('","', "','", x) # replace double quotes for each field
    y = gsub('^"|"$', "'", y) # replace trailing and leading double quotes
    z = paste(y, collapse='\n') # turn it back into a table for fread to read
    df = fread(z, quote="'")
    df
    
       SA SU CC       CN POC PAC
    1: NE  R  0 H "B", O   1   8
    2:  A  A  0        P E,5   8
    

    我无法确认这是否有效,因为我不知道您的文件有多大,但它可能是一种值得的方法。

    【讨论】:

    • 我已经考虑过了,但想知道是否可以使用 fread() 或其他一些读取函数,例如readr::read_delim() 通过参数。阅读 fread() 的文档,它暗示它可以自动处理这些问题,但我不知道如何。
    • 你在 Linux 上吗? fread 具有 cmd 参数,允许在读入文件之前对文件执行代码执行,因此您可以使用 awksed 进行预处理,这样可以避免将其加载到处理前的内存。虽然不确定那里的优势。
    • 我使用的是 Ubuntu 18.04 和 Windows 10。你的意思是通过 fread() 中的input 参数的 shell 命令吗?
    • 我现在无法测试这个,因为我在 win10 上无法访问 *nix,但我认为它会类似于 fread('my_file.csv', cmd="sed s/","/','/g;s/^"|"$/'/g my_file.csv")我强烈建议您在尝试之前创建文件备份!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 2017-09-28
    • 2022-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多