Rcpp 在DataFrame::create(vec1,vec2…)中可以添加多少个向量?

Rcpp 在DataFrame::create(vec1,vec2…)中可以添加多少个向量?,rcpp,Rcpp,我正在创建一个数据帧来保存解析后的haproxy http日志文件,该文件有很多字段(25+) 如果我添加了20多个向量(每个字段一个),我会得到编译错误: no matching function call to 'create' 创建方法: 返回数据帧::创建( _[“clientIp”]=clientIp, _[“客户端端口”]=客户端端口, _[“接受日期”]=接受日期, _[“frontendName”]=frontendName, _[“backendName”]=backendN

我正在创建一个数据帧来保存解析后的haproxy http日志文件,该文件有很多字段(25+)

如果我添加了20多个向量(每个字段一个),我会得到编译错误:

no matching function call to 'create'
创建方法:

返回数据帧::创建(
_[“clientIp”]=clientIp,
_[“客户端端口”]=客户端端口,
_[“接受日期”]=接受日期,
_[“frontendName”]=frontendName,
_[“backendName”]=backendName,
_[“服务器名”]=服务器名,
_[“tq”]=tq,
_[“tw”]=tw,
_[“tc”]=tc,
_[“tr”]=tr,
_[“tt”]=tt,
_[“状态代码”]=状态代码,
_[“字节读取”]=字节读取,
#如果捕获了\u请求\u COOKIE\u字段==1
_[“capturedRequestCookie”]=capturedRequestCookie,
#恩迪夫
#如果捕获了\u请求\u COOKIE\u字段==1
_[“capturedResponseCookie”]=capturedResponseCookie,
#恩迪夫
_[“终止状态”]=终止状态,
_[“actconn”]=actconn,
_[“feconn”]=feconn,
_[“beconn”]=beconn,
_[“srv_conn”]=srvConn,
_[“重试”]=重试,
_[“服务器队列”]=服务器队列,
_[“后端队列”]=后端队列
);
问题

  • 我是否达到了一个严格的极限
  • 是否有一种变通方法允许我向一个数据帧添加20多个向量

  • 是的,您已经达到了一个硬限制--
    Rcpp
    受到C++98标准的限制,该标准要求显式代码膨胀以支持“可变”参数。本质上,必须为使用的每个
    create
    函数生成一个新的重载,并且为了避免阻塞编译器
    Rcpp
    最多只提供20个重载

    一种解决方法是使用“builder”类,在该类中依次添加元素,然后在末尾转换为
    DataFrame
    。这类的一个简单示例——我们创建了一个
    ListBuilder
    对象,然后依次为其添加
    新列。尝试使用此文件运行
    Rcpp::sourceCpp()
    ,以查看输出

    #include <Rcpp.h>
    using namespace Rcpp;
    
    class ListBuilder {
    
    public:
    
       ListBuilder() {};
       ~ListBuilder() {};
    
       inline ListBuilder& add(std::string const& name, SEXP x) {
          names.push_back(name);
    
          // NOTE: we need to protect the SEXPs we pass in; there is
          // probably a nicer way to handle this but ...
          elements.push_back(PROTECT(x));
    
          return *this;
       }
    
       inline operator List() const {
          List result(elements.size());
          for (size_t i = 0; i < elements.size(); ++i) {
             result[i] = elements[i];
          }
          result.attr("names") = wrap(names);
          UNPROTECT(elements.size());
          return result;
       }
    
       inline operator DataFrame() const {
          List result = static_cast<List>(*this);
          result.attr("class") = "data.frame";
          result.attr("row.names") = IntegerVector::create(NA_INTEGER, XLENGTH(elements[0]));
          return result;
       }
    
    private:
    
       std::vector<std::string> names;
       std::vector<SEXP> elements;
    
       ListBuilder(ListBuilder const&) {}; // not safe to copy
    
    };
    
    // [[Rcpp::export]]
    DataFrame test_builder(SEXP x, SEXP y, SEXP z) {
       return ListBuilder()
          .add("foo", x)
          .add("bar", y)
          .add("baz", z);
    }
    
    /*** R
    test_builder(1:5, letters[1:5], rnorm(5))
    */
    
    #包括
    使用名称空间Rcpp;
    类列表生成器{
    公众:
    ListBuilder(){};
    ~ListBuilder(){};
    内联ListBuilder和add(标准::字符串常量和名称,SEXP x){
    名称。推回(名称);
    //注意:我们需要保护我们传入的SEXPs;这里有
    //也许是更好的处理方法,但是。。。
    元素。推回(保护(x));
    归还*这个;
    }
    内联运算符List()常量{
    列出结果(elements.size());
    对于(size_t i=0;i

    PS:With,我们有可变函数,因此限制被删除。

    Rcpp的另一种常见方法是只使用一个外部列表,其中包含您需要的数据帧对象(每个对象受通过老式宏扩展/重复提供的元素数限)在相应的标题中

    在(未测试)代码中:


    Rcpp11是否仍在维护中?
    Rcpp::DataFrame a = Rcpp::DateFrame::create(/* ... */);
    Rcpp::DataFrame b = Rcpp::DateFrame::create(/* ... */);
    Rcpp::DataFrame c = Rcpp::DateFrame::create(/* ... */);
    
    return Rcpp::List::create(Rcpp::Named("a") = a,
                              Rcpp::Named("b") = b,
                              Rcpp::Named("c") = c);