【问题标题】:Passing a `data.table` to c++ functions using `Rcpp` and/or `RcppArmadillo`使用 `Rcpp` 和/或 `RcppArmadillo` 将 `data.table` 传递给 c++ 函数
【发布时间】:2012-12-08 01:30:02
【问题描述】:

有没有办法使用Rcpp 和/或RcppArmadillodata.table 对象传递给c++ 函数,而无需手动将data.table 转换为data.frame?在下面的示例中,test_rcpp(X2)test_arma(X2) 都以 c++ exception (unknown reason) 失败。

R 代码

X=data.frame(c(1:100),c(1:100))
X2=data.table(X)
test_rcpp(X)
test_rcpp(X2)
test_arma(X)
test_arma(X2)

c++ 函数

NumericMatrix test_rcpp(NumericMatrix X) {
    return(X);
}

mat test_arma(mat X) {
    return(X);
}

【问题讨论】:

  • 好,它应该是这样工作的......

标签: r data.table rcpp


【解决方案1】:

在其他答案的基础上,这里是一些示例代码:

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
double do_stuff_with_a_data_table(DataFrame df){
    CharacterVector x = df["x"] ;
    NumericVector   y = df["y"] ;
    IntegerVector   z = df["v"] ;

    /* do whatever with x, y, v */
    double res = sum(y) ;
    return res ;
}

因此,正如 Matthew 所说,这会将 data.table 视为 data.frame(在 Rcpp 中也称为 Rcpp::DataFrame)。

require(data.table)
DT <- data.table(
    x=rep(c("a","b","c"),each=3), 
    y=c(1,3,6), 
    v=1:9)
do_stuff_with_a_data_table( DT ) 
# [1] 30

这完全忽略了data.table 的内部结构。

【讨论】:

    【解决方案2】:

    尝试将data.table 传递为DataFrame 而不是NumericMatrix。无论如何,它是data.frame,具有相同的结构,因此您不需要转换它。

    【讨论】:

      【解决方案3】:

      Rcpp 位于编码为 SEXP 的 native R 类型之上。这包括例如data.framematrix

      data.table 不是原生的,它是一个附加组件。所以想要这个的人(你?)必须编写一个转换器,或者为其他人提供资金来编写一个。

      【讨论】:

      • 他不能把它作为data.frame而不是NumericMatrix传递吗?
      • 是的@MatthewDowle,Rcpp::DataFrame 遮住了 R 数据框。 data.table 有 C api 吗?
      • @RomainFrancois。伟大的。然后在 Rcpp 中,他可以像对待 DataFrame 一样对待 data.table。这是一个相同的结构,只是到处都有一个额外的属性。我没有做任何特别的事情来提供 C api - 我应该这样做吗?
      • 感谢@RomainFrancois 和 Dirk。我已经可以在 Rcpp 中使用 as DataFrame 看到很多好处。如果有人需要,很高兴调查 DataTable Rcpp 类...
      • 如果确实有需要,何乐而不为。我想这将是额外的,因为我们不想依赖彼此的包。但是在RcppDataTable 包或其他任何东西上的共同努力..
      【解决方案4】:

      作为参考,我认为从rcpp 输出一个列表作为data.table 允许通过列表更新。

      这是一个虚拟示例:

      cCode <- 
          '
           DataFrame DT(DTi);
           NumericVector x = DT["x"];
           int N = x.size();
           LogicalVector b(N);
           NumericVector d(N);
           for(int i=0; i<N; i++){
               b[i] = x[i]<=4;
               d[i] = x[i]+1.;
           }
           return Rcpp::List::create(Rcpp::Named("b") = b, Rcpp::Named("d") = d);
          ';
      
      require("data.table");
      require("rcpp");
      require("inline");
      DT <- data.table(x=1:9,y=sample(letters,9)) #declare a data.table
      modDataTable <- cxxfunction(signature(DTi="data.frame"), plugin="Rcpp", body=cCode)
      
      DT_add <- modDataTable(DT)  #here we get the list
      DT[, names(DT_add):=DT_add] #here we update by reference the data.table
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-03
        相关资源
        最近更新 更多