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