【问题标题】:Is it possible to direct fread within data.table package to skip erroneous rows是否可以在 data.table 包中引导 fread 跳过错误的行
【发布时间】:2014-06-29 08:28:58
【问题描述】:

data.table 1.9.2

我正在阅读一张大表,似乎至少有一行会产生以下性质的错误:

Error in fread(paste(base_dir, filename, sep = "")) : 
Expected sep ('|') but '' ends field 23 on line 190333 when reading data:...

是否可以直接在data.table 包中的 fread 跳过错误的行?

或者我将来可以通过其他方式解决此类错误吗?

【问题讨论】:

  • 我不能说。但即使如此 - 如果确实如此,那么我想跳过它是一个错误的行。我意识到这可能非常困难,因为基本上需要 fread 才能知道错误行中有多少个分隔符。也许在这种情况下,我的问题的答案是否定的,但我只是想以防万一。
  • 您能否发布readLines 的输出,例如,190333 行之前的 3 行和之后的 3 行?您是否在 fread 中指定了 sep
  • count.fields() 可以成为你的朋友。连同fread() 中的skipnrows 参数
  • @bibzzzz 这个问题已经得到解答,或者您是否找到了替代解决方案。如果是这样,请接受任何答案或发布+接受您自己的答案或提供有关缺失内容的详细信息。

标签: r data.table fread


【解决方案1】:

一种解决方法如果您希望跳过错误行

首先使用sep="\n"读取文件仅根据新行分隔然后计算每行的分隔符数量并过滤正确的分隔符#然后collapse数据并根据真正的列分隔符进行分隔.请参阅下面的示例。

示例数据:

require(data.table)

wrong <- fread("
var1|var2|var3|var4
a|1|10|TRUE
b|2|10|FALSE
c|3|10FALSE      # note the missing separator between 10 and FALSE.
d|4|10|TRUE
e|5|10|TRUE",sep="\n")

计算字符串数:

有多种方法可以做到这一点,请参阅stringr?str_count 之一:

wrong[,n_seps := str_count(wrong[[1]],fixed("|"))] # see below for explanation.

或者通过rcpp 类似物进行一些简化假设:

如果分隔符是单个字符(通常是),那么我发现下面的简单函数最有效。它写成c++ 并通过Rcpp 包的sourceCpp() 主力导出到R

在单独的“helpers.cpp”文件中

    #include <Rcpp.h>
    #include <algorithm>
    #include <string>

    using namespace Rcpp;
    using namespace std;

    // [[Rcpp::export]]

    NumericVector v_str_count_cpp(CharacterVector x, char y) {
        int n = x.size();
        NumericVector out(n);

        for(int i = 0; i < n; ++i) {
            out[i] = std::count(x[i].begin(), x[i].end(), y);
        }
        return out;
    }

带有计数的新列:

然后我们应用该函数计算每一行出现| 的次数并返回结果 在名为n_seps 的新列中。

wrong[,n_seps := apply(wrong,1,v_str_count_cpp,"|")]

现在wrong 看起来像:

> wrong
var1|var2|var3|var4 n_seps
1:         a|1|10|TRUE      3
2:        b|2|10|FALSE      3
3:         c|3|10FALSE      2
4:         d|4|10|TRUE      3
5:         e|5|10|TRUE      3

现在过滤漂亮的行并将其折叠回来:

collapsed <- paste0( wrong[n_seps == 3][[1]], collapse = "\n" )

最后用适当的分隔符读回它:

correct <- fread(collapsed,sep="|")

看起来像:

> correct
V1 V2 V3    V4
1:  a  1 10  TRUE
2:  b  2 10 FALSE
3:  d  4 10  TRUE
4:  e  5 10  TRUE

希望这会有所帮助。

【讨论】:

  • 不错的答案。由于内存限制,我不得不writeLines 而不是粘贴和折叠。
  • 这适用于我正在尝试做的事情,非常感谢。感谢您花时间解释内部工作原理
【解决方案2】:

没有。没有选择让 fread 这样做。

GitHub 上有关于它的讨论,但没有说明应该使用什么选项让 fread 跳过这些行(此处:https://github.com/Rdatatable/data.table/issues/810

【讨论】:

    猜你喜欢
    • 2014-10-28
    • 1970-01-01
    • 2015-12-30
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多