使用`Rcpp`和/或`RcppArmadillo将`data.table`传递给c ++函数

时间:2012-12-08 01:30:02

标签: r data.table rcpp

有没有办法使用data.table和/或RcppRcppArmadillo个对象传递给c ++函数,而无需手动转换为data.tabledata.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);
}

4 个答案:

答案 0 :(得分:12)

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

#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 ;
}

因此,正如马修所说,这会将data.table视为data.frameRcpp::DataFrame中的Rcpp

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的内部。

答案 1 :(得分:9)

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:3)

作为参考,我认为好的方法是从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