您可以使用逗号/制表符/任何带分隔符的文本文件计算每行的字段数utils::count.fields.
这是一个可重复的例子:
d <- data.frame(
x = c(1, NA, 3, NA, 5),
y = c(NA, "b", "c", NA, NA),
z = c(NA, "beta", "gamma", NA, "epsilon")
)
fname <- "test.csv"
write.csv(d, fname, na = "", row.names = FALSE)
count.fields(fname, sep = ",")
## [1] 3 3 3 3 3 3
Run Code Online (Sandbox Code Playgroud)
我想计算每行的非空字段数.我可以通过读取所有内容并计算不是的值的数量,以笨重的方式做到这一点NA.
d2 <- read.csv(fname, na.strings = "")
rowSums(!is.na(d2))
## [1] 1 2 3 0 2
Run Code Online (Sandbox Code Playgroud)
我真的很喜欢扫描文件的方式(比如count.fields),所以我可以针对特定的部分进行读取.
有没有更好的方法来计算分隔文件中的非空字段数?
如果安装了Rcpp&BHpackages,这应该是完全可移植的:
library(Rcpp)
library(inline)
csvblanks <- '
string data = as<string>(filename);
ifstream fil(data.c_str());
if (!fil.is_open()) return(R_NilValue);
typedef tokenizer< escaped_list_separator<char> > Tokenizer;
vector<string> fields;
vector<int> retval;
string line;
while (getline(fil, line)) {
int numblanks = 0;
Tokenizer tok(line);
for(Tokenizer::iterator beg=tok.begin(); beg!=tok.end(); ++beg){
numblanks += (beg->length() == 0) ? 1 : 0 ;
};
retval.push_back(numblanks);
}
return(wrap(retval));
'
count_blanks <- rcpp(
signature(filename="character"),
body=csvblanks,
includes=c("#include <iostream>",
"#include <fstream>",
"#include <vector>",
"#include <string>",
"#include <algorithm>",
"#include <iterator>",
"#include <boost/tokenizer.hpp>",
"using namespace Rcpp;",
"using namespace std;",
"using namespace boost;")
)
Run Code Online (Sandbox Code Playgroud)
一旦获得该源,您就可以调用count_blanks(FULLPATH)它,它将返回每行空白字段计数的数字向量.
我针对这个文件运行它:
"DATE","APIKEY","FILENAME","LANGUAGE","JOBID","TRANSCRIPT"
1,2,3,4,5
1,,3,4,5
1,2,3,4,5
1,2,,4,5
1,2,3,4,5
1,2,3,,5
1,2,3,4,5
1,2,3,4,
1,2,3,4,5
1,,3,,5
1,2,3,4,5
,2,,4,
1,2,3,4,5
Run Code Online (Sandbox Code Playgroud)
通过:
count_blanks("/tmp/a.csv")
## [1] 0 0 1 0 1 0 1 0 1 0 2 0 3 0
Run Code Online (Sandbox Code Playgroud)
CAVEATS
header带有相关C/C++代码的逻辑参数(这将非常简单).[:space:]+)视为"空",那么你需要的东西比调用要复杂得多length.如果需要,这是一种处理它的潜在方法.escaped_list_separator定义的Boost功能的默认配置.也可以使用引号和分隔符来定制(可以进一步模仿/ .read.csvread.table这将更接近count.fields/ C_countfields性能,并且将通过读取每一行来消除消耗内存的需要,只是为了找到最终想要更优化目标的行.我不认为为返回的数字向量预分配空间会增加速度,但是你可以在这里看到讨论,如果需要的话,它会显示如何做.