是否可以在data.table包中引导fread来跳过错误的行

bib*_*zzz 6 r fread data.table

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:...
Run Code Online (Sandbox Code Playgroud)

是否有可能在data.table包中引导fread 跳过错误的行?

或者我将来可以解决这种错误的任何其他方式?

npj*_*pjc 6

如果您希望跳过错误的行,可以采用一种解决方法:

首先在文件中读取只根据新行分开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")
Run Code Online (Sandbox Code Playgroud)

count个字符串数:

在许多的方法可以做到这一点,看到stringr?str_count一个:

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

或者通过rcpp类比的一些简化假设:

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

在一个单独的"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;
    }
Run Code Online (Sandbox Code Playgroud)

带有计数的新列:

然后,我们应用该函数来计算|每行的出现次数,并将结果返回到一个名为的新列中n_seps.

wrong[,n_seps := apply(wrong,1,v_str_count_cpp,"|")]
Run Code Online (Sandbox Code Playgroud)

现在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
Run Code Online (Sandbox Code Playgroud)

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

collapsed <- paste0( wrong[n_seps == 3][[1]], collapse = "\n" )
Run Code Online (Sandbox Code Playgroud)

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

correct <- fread(collapsed,sep="|")
Run Code Online (Sandbox Code Playgroud)

看起来像:

> 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
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.