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

11

是否有一种方法可以在不手动转换 data.tabledata.frame 的情况下,使用 Rcpp 和/或 RcppArmadillodata.table 对象传递给 C++ 函数? 在下面的示例中,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);
}

1
好的,这就是它应该工作的方式... - Dirk Eddelbuettel
4个回答

13

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

#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 :: DataFrameRcpp中)。

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


10

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


6

Rcpp 位于以 SEXP 编码的本地 R 类型之上,其中包括例如 data.framematrix

data.table 并不是本地类型,它是一个插件。因此,想要使用它的人(您?)必须编写转换器,或提供资金让其他人编写转换器。


他不能只将它作为data.frame传递,而不是NumericMatrix吗? - Matt Dowle
是的@MatthewDowle,Rcpp :: DataFrame遮蔽了R数据框。data.table是否有C API? - Romain Francois
@RomainFrancois。太好了。然后在Rcpp中,他可以像处理DataFrame一样处理data.table。它是完全相同的结构,只是有时会有额外的属性。我没有做任何特殊的事情来提供C API - 我应该吗? - Matt Dowle
2
感谢@RomainFrancois和Dirk。我已经看到在Rcpp中使用DataFrame的好处很多。如果有人需要,我很乐意研究DataTable Rcpp类... - Matt Dowle
3
如果确实有需求,为什么不呢。我想这将是额外的东西,因为我们不希望依赖彼此的包。但是,可以共同努力开发一个 RcppDataTable 包或其他类似的包。 - Romain Francois
显示剩余2条评论

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接