read_csv()解析错误信息,如何解释?

13

我正在处理大量CSV数据。这些数据有点“脏”,因为它们具有不一致的分隔符、杂乱无章的字符和格式问题,这些都会给read_csv()带来问题。

但是,我的问题并不在于数据的混乱程度,而仅仅是尝试理解read_csv()给出的解析错误。如果我能更好地理解错误信息,那么我就可以编写一些脚本进行修复,以解决这个问题。 由于数据量太大,手动处理是不可行的。

以下是一个最简示例。假设我有一个类似于以下内容的CSV文件:

"col_a","col_b","col_c"
"1","a quick","10"
"2","a quick "brown" fox","20"
"3","quick, brown fox","30"

注意第二行中"brown"周围存在错误引号。该内容存储在名为"my_data.csv"的文件中。

当我尝试读取该文件时,出现了一些解析失败。

> library(tidyverse)
> df <- read_csv("./my_data.csv", col_types = cols(.default = "c"))
Warning: 2 parsing failures.
row # A tibble: 2 x 5 col     row   col           expected actual            file expected   <int> <chr>              <chr>  <chr>           <chr> actual 1     2 col_b delimiter or quote      b './my_data.csv' file 2     2 col_b delimiter or quote        './my_data.csv'

如您所见,解析失败消息并不是“漂亮打印”的。它是一个271个字符的长行。

我无法确定在故障消息中甚至应该放置换行符以查看问题出在哪里以及消息试图告诉我什么。此外,它涉及到一个“2x5 tibble”。什么tibble?我的数据框是3x3。

有人可以向我展示如何格式化或在read_csv()消息中插入换行符,以便我可以看到它如何检测到问题吗?

是的,我知道在这个特定的最小示例中问题是什么。在我的实际数据中,我正在处理大量csv(约1M行),其中夹杂着不一致性,这些不一致性会向我投掷数百个解析失败。我想设置一个将其分类和以编程方式处理的工作流程。我认为第一步只是了解如何“解析”解析失败消息。


2
尝试使用read.csv而不是read_csv。您的示例在前者中给出了更合理的答案,因此在处理完整数据集时可能效果更好。 - Andrew Gustar
1
如果您的文件不是一个正确的CSV文件,那么read_csv将无法提供太多帮助。就像在编程中一样,您得到的错误消息并不总是解决实际问题。也许可以尝试使用CSV验证器 - MrFlick
1
如果这是特定于read_csv的,则应删除对read.csv的引用,因为那会让人感到困惑(它们是两个完全不同的函数)。后者来自“tidyverse”中的readr包,其中tibbles替换了data.frames。如果您有不平衡的引号,则所有换行符都包含在最后一个打开的引号中,因此一个值可能占据文件中的多行。R无法知道如何将其分解。 - MrFlick
2
最坏的情况下,您可以使用readLines将每行作为整体读取,然后尝试检测有问题的行并清理它们。 - Gregor Thomas
1
之前遇到过类似的问题,我会选择@Gregor的建议。你也可以尝试使用“sed”,这是一个带有data.table的bash csv工具。请参阅:https://dev59.com/I33aa4cB1Zd3GeqPbE38 - detroyejr
显示剩余3条评论
1个回答

17

看了一下实际的文档,我发现有一种方法可以以非常可用的形式获取read_csv()中的解析失败信息

只需使用problems()即可获取解析失败信息。

> library(tidyverse)
> df <- read_csv("./my_data.csv", col_types = cols(.default = "c"))
Warning: 2 parsing failures.
row # A tibble: 2 x 5 col     row   col           expected actual            file expected   <int> <chr>              <chr>  <chr>           <chr> actual 1     2 col_b delimiter or quote      b './my_data.csv' file 2     2 col_b delimiter or quote        './my_data.csv'

> parsing_failures <- problems(df)
> parsing_failures
# A tibble: 2 x 5
    row   col           expected actual            file
  <int> <chr>              <chr>  <chr>           <chr>
1     2 col_b delimiter or quote      b './my_data.csv'
2     2 col_b delimiter or quote        './my_data.csv'

显然,read_csv()会关联一个包含解析失败细节的tibble,并且可以通过将read_csv的结果传递给problems()来访问它。


1
谢谢,这正是我想要的。 - Docconcoct

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接