【问题标题】:How do I read in a csv with two double quotes as text qualifiers using R?如何使用 R 读取带有两个双引号作为文本限定符的 csv?
【发布时间】:2019-02-15 17:20:41
【问题描述】:

如何在 csv 中读取 2 个双引号作为限定符,并在限定符中使用逗号,即

""V"",""W"",""X"",""Y"",""Z""
""            "",""A                    "",""*B           "",""C                  "",""D-E""
""            "",""a                     "",""*b            "",""c,c,c"",""d e         ""
""            "",""E                    "",""*F           "",""G                   "",""H-H""

在data.table 中使用fread?

【问题讨论】:

  • 您可能希望在导入之前准备好文件,例如 sed 's/""/"/g' input_file > output_file(或 sed -i,仅替换 input_file)
  • Tensibai 的解决方案会更高效,但是如果您不在 unix 系统上并且没有 sed,您可以只导入带双引号的文件(使用 fread)然后执行在 R fread(<your-file>, quote = '')[, lapply(.SD, function(x) gsub('^\"\"|\"\"$', '', x))] 中替换,但可能需要一段时间,具体取决于您的机器(您只需执行一次,然后将新数据框保存到不带双引号的文件中)
  • 我可能应该提到的问题是,有时文本限定符中会有逗号。所以fread实际上无法读取数据。我会进行必要的编辑。
  • 您能否发布一个包含 10 行代表您遇到的问题类型的示例文件?

标签: r csv data.table


【解决方案1】:

根据要求使用data.table 和fread,您可以执行此操作。

诀窍是

  1. 通过设置sep='~'(或文件中不存在的其他字符)和设置quote=''(无引号)将文件中的每一行作为一个列读取。
  2. 然后,删除行首和行尾的双引号
  3. tstrsplit() 使用"","" 作为模式将单列分成多列

data.table::tstrsplit() 是strsplit() 的便捷包装器,可将转置为列的行返回。

R 代码:

library(data.table)
# Read the file as a single column per line by picking 
#  a sep character that doesn't exist in the file. 
#  E.g. '~' doesn't exist in the OP's current sample data

DT <- fread( "OPs_new_input_example_file.csv", 
             sep='~', quote='', header=FALSE)

DT[, V1 := gsub('""(.*)""$', "\\1",V1)] # remove "" at start and end
DT <- DT[, tstrsplit(V1, '"",""') ] # strsplit and transpose rows to columns
DT

结果:

             V1                     V2             V3                   V4           V5
1:            V                      W              X                    Y            Z
2:               A                      *B             C                            D-E
3:              a                      *b                            c,c,c d e         
4:               E                      *F            G                   

请随时发布改进建议或替代解决方案。

【讨论】:

  • 谢谢你的回答,很创新,但是还是有一些问题。我添加了一个中断我的编辑的示例。错误说它需要 5 个字段,但找到了 7 个。这对我来说很奇怪。
  • 我明白你的意思。问题是 fread 将逗号作为分隔符放在其他任何东西之前。我将尝试通过在 fread 中使用 quote='"' 来修改解决方案以解决该问题,然后修改 gsub 调用以查找剩余的单引号。
  • 在第一阶段无法解决 fread 拿起逗号的问题,因此发布了上述替代解决方案。
  • 啊,这是一个特殊的解决方案!做得好!你不应该一直分配吗?
  • 如上在 j 中使用:= 是“就地分配”。由于列 V1 已经存在,它会替换原始值。
猜你喜欢
  • 1970-01-01
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 2019-03-28
相关资源
最近更新 更多