【问题标题】:R data.table problem when read file with inconsistent column读取具有不一致列的文件时的R data.table问题
【发布时间】:2021-02-26 14:47:46
【问题描述】:

当我使用 R data.table(fread) 读取 dat 文件 (3GB) 时出现问题:

在第 3169933 行提前停止。预期有 136 个字段,但找到了 138 个。考虑 fill=TRUE 和 comment.char=。第一个丢弃的非空行:

我的代码:

library(data.table)
file_path = 'data.dat' # 3GB
fread(file_path,fill=TRUE)

问题是我的文件有大约 500 万行。详细:

  • 从第 1 行到第 3169933 行共有 136 列
  • 从第 3169933 行到第 5000000 行共有 138 列

fread() 由于此错误,仅将我的文件读取到第 3169933 行。 fill = TRUE 在这种情况下没有帮助。谁能帮帮我?

R 版本:3.6.3 data.table 版本:1.13.2

在这种情况下有关 fill=TRUE 的注意事项:

[案例 1- 不是我的案例] 如果我的文件的第 1 部分(50% 行)有 138 列,第 2 部分有 136 列,那么 fill=TRUE 会有所帮助(它将用 NA 填充第 2 部分中的两列)

[案例 2- 我的案例] 如果我的文件的第 1 部分(50% 行)有 136 列,第 2 部分有 138 列,那么在这种情况下填充 =TRUE 将无济于事。

【问题讨论】:

  • 平台? R 版本?
  • stackoverflow.com/questions/44464441/…分别导入两块数据后。或者使用 awk 将“,NA,NA”附加到前 3169933 行。
  • 什么意思是“fill = TRUE 没有帮助” - 如果您使用 fill=TRUE 会出现什么问题?
  • @VasilyA :当我设置 fill=TRUE 时,错误仍然出现:在第 316993 行提前停止,预期 136 个字段,但找到 138 个。
  • @Severin Pappadeux:我使用 R studio,R 版本:3.6.3,data.table 版本:1.13.2

标签: r data.table fread


【解决方案1】:

尝试单独阅读它们,在为第一部分创建两个额外的列后将它们组合起来。

first_part = fread('data.dat', nrows = 3169933) %>%
  mutate(extra_1 = NA, extra_2 = NA)

second_part = fread('data.dat', skip = 3169933)
df = bind_rows(first_part, second_part)

【讨论】:

  • @Anderson Zhu:谢谢你的帮助。问题是某些 DAT 文件将在第 3169933 行中更早停止,其他文件将在不同行中更早停止(例如:第 2886321 行或 3500212....)。在一般情况下,我无法使用特定数字设置 nrows。我也尝试从这个警告错误中提取与行号问题相关的字符串(例如本例中的 3169933),但不可行。你有什么建议如何从这个警告错误中提取与行号问题相关的字符串?如果识别出错误行,我可以将此文件分成两部分,然后按照您的建议合并到一个文件中。
  • 另一种可能的解决方案是逐行读取数据,以便检查每行的列数。见stackoverflow.com/questions/11664075/import-dat-file-into-r希望这会有所帮助。
  • @Anderson Zhu:非常感谢您的积极支持。我将尝试此解决方案并与上述方法进行比较!
【解决方案2】:

不知道为什么即使使用fill=T 仍然存在问题...但是如果没有任何帮助,您可以尝试使用以下方法:

tryCatch(
  expr    = {dt1 <<- fread(file_path)},
  warning = function(w){
    cat('Warning: ', w$message, '\n\n');
    n_line <- as.numeric(gsub('Stopped early on line (\\d+)\\..*','\\1',w$message))
    if (!is.na(n_line)) {
      cat('Found ', n_line,'\n')
      dt1_part1 <- fread(file_path, nrows=n_line)
      dt1_part2 <- fread(file_path, skip=n_line)
      dt1 <<- rbind(dt1_part1, dt1_part2, fill=T)
    }
  },
  finally = cat("\nFinished. \n")
);

tryCatch() 构造捕获警告消息,因此您可以提取行号并进行相应的处理。

【讨论】:

  • 关于 fill=TRUE: [案例 1] 如果我的文件的第 1 部分有 138 列,第 2 部分有 136 列,那么 fill=TRUE 会有所帮助(它将用 NA 填充第 2 部分中的两列) 但是 [案例 2] 如果我的文件的第 1 部分有 136 列,第 2 部分有 138 列,那么在这种情况下填充 =TRUE 将无济于事。在案例 2 中,您的解决方案将有助于顺利读取此文件。再次感谢您!
猜你喜欢
  • 2020-12-28
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
相关资源
最近更新 更多