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 跳过错误的行?
或者我将来可以解决这种错误的任何其他方式?
如果您希望跳过错误的行,可以采用一种解决方法:
首先在文件中读取只根据新行分开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)
在许多的方法可以做到这一点,看到stringr的?str_count一个:
wrong[,n_seps := str_count(wrong[[1]],fixed("|"))] # see below for explanation.
Run Code Online (Sandbox Code Playgroud)
或者通过rcpp类比的一些简化假设:
如果分隔符是单个字符(它通常是),那么我发现下面的简单函数是最有效的.它是通过包的主力书写c++并导出的.RRcppsourceCpp()
#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)
希望这可以帮助.