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

时间:2014-05-12 04:45:38

标签: r data.table fread

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跳过错误的行?

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

2 个答案:

答案 0 :(得分: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")

计算字符串数:

有多种方法可以执行此操作,请参阅stringr的{​​{1}}获取一个:

?str_count

或通过wrong[,n_seps := str_count(wrong[[1]],fixed("|"))] # see below for explanation. 类似物进行一些简化假设:

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

单独的“helpers.cpp”文件

sourceCpp()

包含计数的新列:

然后我们应用该函数来计算每行 #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="|")

希望这有帮助。

答案 1 :(得分:0)

没有。没有选择让他做这件事。

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