【问题标题】:read_csv() parsing error message, how to interpret?read_csv() 解析错误信息,如何解释?
【发布时间】:2018-03-28 11:29:18
【问题描述】:

我正在解析大量 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"

请注意,第二行的“棕色”周围有虚假引号。此内容进入名为“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'

如您所见,解析失败并没有被“漂亮地打印出来”。它是 ONE LONG LINE,共 271 个字符。

我什至无法确定在失败消息中的何处放置换行符,以查看问题出在哪里以及消息试图告诉我什么。此外,它指的是“2x5 tibble”。什么小标题?我的数据框是 3x3。

谁能告诉我如何格式化或在来自 read_csv() 的消息中添加换行符,以便我了解它是如何检测问题的?

是的,我知道这个特定的最小示例中的问题是什么。在我的实际数据中,我正在处理大量的 csv(~1M 行),其中充斥着不一致的地方,这让我遇到了数百次解析失败。我想设置一个工作流来对这些进行分类并以编程方式处理它们。我认为,第一步只是了解如何“解析”解析失败消息。

【问题讨论】:

  • 尝试使用read.csv 而不是read_csv。您的示例对前者给出了更明智的答案,因此它可能在您的完整数据集上效果更好。
  • 如果您的文件不是正确的 CSV 文件,那么 read_csv 将不会有那么大的帮助。就像代码一样,您收到的错误消息并不总是能解决真正的错误。也许试试CSV validator
  • 如果这是特定于read_csv,那么您应该删除对read.csv 的引用,因为这会造成混淆(它们是两个完全不同的函数)。后者来自readr 包,它是tibbles 替换data.frames 的“tidyverse”的一部分。如果您的引号不平衡,则所有换行符都包含在最后一个打开的引号中,因此一个值可能会占用文件中的很多行。 R 无法知道在哪里分解它。
  • 在最坏的情况下,您可以使用readLines 将每一行作为一个整体读取,然后您可以尝试检测有问题的行并进行清理。
  • 不久前遇到过类似的问题,我会选择@Gregor。您也可以尝试使用“sed”,它是一个带有 data.table 的 bash csv 实用程序。见:stackoverflow.com/questions/22229109/…

标签: r csv parsing tidyverse readr


【解决方案1】:

深呼吸并查看实际文档后,I see there is a way to get the parsing failures from read_csv() in a form that is very usable

我所要做的就是使用 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() 来访问它。

【讨论】:

  • 谢谢,这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-04
  • 2013-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多