数据表 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包跳过错误的行?或者我可以在将来解决此类错误的任何其他方式?
最佳答案
如果您希望 的一种解决方法跳过 错误的行:
首先使用 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++
并导出到 R
通过 Rcpp
包裹的sourceCpp()
主力。在单独的“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
希望这可以帮助。
关于r - 是否可以在 data.table 包中直接 fread 跳过错误的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23601202/