R 如何计算分隔文件中非空字段的数量?
您可以使用R 如何计算分隔文件中非空字段的数量?,r,csv,import,R,Csv,Import,您可以使用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 =
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
我真的想要一种扫描文件的方法(比如count.fields
),这样我就可以针对特定的部分进行读取
是否有更好的方法来计算分隔文件中非空字段的数量?如果您安装了
Rcpp
&BH
软件包,则此方法应完全可移植:
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;")
)
通过:
注意事项
- 很明显,它没有忽略头部,因此它可以使用
逻辑参数和关联的C/C++代码(这将非常简单)头部
- 如果将“空格”(即
)计算为“空”,则需要比调用[:space::+
更复杂的内容。如果需要的话,这是一种潜在的解决方法length
- 它使用已定义的Boost函数
的默认配置。还可以使用引号和分隔符对其进行自定义(从而可以进一步模拟转义列表\u分隔符
/read.csv
)read.table
这将更接近count.fields/
C\u countfields
性能,并将消除通过读取每一行来消耗内存的需要,而只是为了找到您最终想要更优化的目标行。我不认为为返回的数字向量预分配空间会增加很多速度,但您可以看到显示如何在需要时执行此操作的讨论。我刚刚意识到您想要计算非空,我希望这一点的反面足够琐碎,不需要编辑;-)
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;")
)
"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
count_blanks("/tmp/a.csv")
## [1] 0 0 1 0 1 0 1 0 1 0 2 0 3 0