【问题标题】:R: How to read in file and skip lines that have errors with fread function?R:如何读取文件并跳过 fread 函数有错误的行?
【发布时间】:2021-08-13 22:17:37
【问题描述】:

我正在尝试使用 fread 函数读取 CSV 文件,但在读取它时会破坏行中多余字符的原因。所以我想知道是否有办法读取文件,跳过有错误的行,然后继续阅读?谢谢你的任何建议。 下面,你可以看到我得到的错误

在 fread("data.csv", : 在第 617854 行提前停止。预期有 52 个字段,但找到了 54 个。考虑 fill=TRUE 和 comment.char=。第一个丢弃的非空行:

【问题讨论】:

  • 您是否尝试过错误消息建议的推荐参数?
  • 但出于多种原因,我认为您的问题的答案是“否”,没有办法让fread 跳过有问题的行并继续阅读。我希望其他人知道在这里证明我错了的方法,...
  • 是的,我尝试了错误消息建议但没有运气,您知道其他解决方法吗?该文件非常大(大约 10gb),这就是我使用 fread 函数的原因

标签: r error-handling data.table


【解决方案1】:

我认为您可以使用freadnrowsskip 参数来自己做这件事。我没有适当损坏的 csv 来测试它,所以没有保证这会起作用,但可能类似于下面的东西。这基本上是一种尝试自动获取警告中标记的行号,并恢复读取该行之后所有行的csv。

基本上我一次读取 100,000 行数据,如果成功,我会将这些数据写入名为 data_chunkslist。如果它发出警告,我会拿起警告消息,使用一些正则表达式来确定行号是什么,然后阅读该行。然后我返回data.table 并写入data_chunks 列表。然后,我将rows_to_skip 值更新为data_chunks 中所有data.tables 中的行数,加上问题行数(我返回bad_row 布尔值以及data.table 以表明这一点,并且在每次迭代时将其添加到 bad_rows)。

它都在一个while循环中,所以会一直执行直到rows_to_skip的数量超过要读取的行数,在这种情况下,会抛出一个错误并且if语句会触发@987654337 @,然后退出循环。最后,使用rbindlist 将列表中的所有行绑定在一起。这感觉很 hacky,可能不是那么可靠,但为了将您的数据加载到 R 中,它至少可能是一个开始:

data_chunks <- list()
i <- 1
rows_to_skip <- 0
rows_to_read <- 100000
bad_rows <- 0
file_name <- "my.csv"

while (TRUE) {
  
  out <- tryCatch(
    list(
      data = data.table::fread(file_name, nrows = rows_to_read, skip = rows_to_skip, header = FALSE),
      bad_row = FALSE
    ),
    error = function(e) {
      e
    },
    warning = function(w) {
      warn_msg <- conditionMessage(w)
      warn_matches <- regexec("line (\\d+)", warn_msg)
      rows_to_read <- as.numeric(regmatches(warn_msg, warn_matches)[[1]][2]) - 1
      if (!is.na(rows_to_read)) {
        list(
          data = data.table::fread(file_name, nrows = rows_to_read, skip = rows_to_skip, header = FALSE),
          bad_row = TRUE
        )
      } else {
        NULL
      }
    })
  
  if ("error" %in% class(out) || is.null(out)) {
    break
  } else {
    data_chunks[[i]] <- out[["data"]]
  }

  bad_rows <- bad_rows + out[["bad_row"]]
  rows_to_skip <- sum(sapply(data_chunks, nrow)) + bad_rows
  i <- i + 1
  
}

mydata <- data.table::rbindlist(data_chunks, use.names = FALSE)

【讨论】:

  • 非常感谢,经过几次调整,效果刚刚好
猜你喜欢
  • 2018-06-08
  • 1970-01-01
  • 2014-03-14
  • 2020-10-07
  • 2016-10-10
  • 2013-07-08
  • 1970-01-01
  • 2015-12-30
  • 2022-01-13
相关资源
最近更新 更多