【问题标题】:Understanding passing armadillo matrices to R functions via RInside了解通过 RInside 将犰狳矩阵传递给 R 函数
【发布时间】:2012-11-03 03:14:40
【问题描述】:

我正在尝试通过 RInside 在 C++ 中使用 R。我无法将犰狳矩阵传递给 R 并返回结果。下面我能够从 R 库函数返回结果,但是我得到了错误的结果。我正在使用时刻包中的偏度函数作为示例,它在 R 中应该可以工作。我检查了 RInside 中的示例,但我仍然不确定如何使用 RcppArmadillo。如何正确地将 c++ 中的犰狳矩阵传递给 R?

    #include <RInside.h>                   
    #include <RcppArmadillo.h>

    using namespace std;
    using namespace arma;

    int main(int argc, char *argv[]) {
        RInside R(argc, argv);  


        string R_libs = "suppressMessages(library(moments));";

        R.parseEvalQ(R_libs);

        mat A = randu<mat>(5,5);

        R["A"] = A;

        string R_skewness = "B <- skewness(A);";
        //this fails
        mat B = Rcpp::as<mat>(R.parseEval(R_skewness)); //terminate called after throwing an instance of 'Rcpp::not_a_matrix'   

        //this works but wrong
        mat B = Rcpp::as<vec>(R.parseEval(R_skewness)); // returns only 1 number, should be 5 ( 1 for each columnn), same result if i change mat B to vec B
        exit(0);
 }

【问题讨论】:

    标签: c++ r rcpp armadillo rinside


    【解决方案1】:

    我们实现as&lt;mat&gt; 的方式要求您传递的R 对象是一个矩阵。在您的示例中,B 是一个向量:

    > A <- matrix( runif(25), ncol = 5)
    > A
               [,1]      [,2]       [,3]       [,4]      [,5]
    [1,] 0.19215339 0.5857249 0.14345222 0.32154176 0.6162155
    [2,] 0.95753898 0.9618379 0.06239842 0.06200197 0.7044018
    [3,] 0.33575790 0.1372804 0.03027635 0.62662467 0.9778451
    [4,] 0.16504957 0.1919765 0.49176372 0.94841456 0.2914772
    [5,] 0.01570709 0.8055231 0.51218581 0.79562809 0.6939380
    > B <- skewness( A )
    > B
    [1]  1.15196587 -0.04547576  0.32186257 -0.30788111 -0.29251009
    

    为了转换为arma::vec,我不会重现您看到的行为。 arma::vec 有 3 个元素:

    require( RcppArmadillo )    ## and make sure you have Rcpp 0.10.0 or later
    
    sourceCpp( code = '
    // [[Rcpp::depends("RcppArmadillo")]]
    
    #include <RcppArmadillo.h>
    
    using namespace arma ; 
    using namespace Rcpp ;
    
    // [[Rcpp::export]]
    List foo( NumericVector x){
        vec B = Rcpp::as<vec>(x); 
    
        return List::create( 
            _["nrows"] = B.n_rows,
            _["ncols"] = B.n_cols
        ) ;
    
    }
    ')
    foo( c(1, 2, 3 ) )
    # $nrows
    # [1] 3
    # 
    # $ncols
    # [1] 1
    

    【讨论】:

    • 为第一个官方sourceCpp()-使用答案:) 喝彩 :)
    • 稍微澄清一下。
    • 所以我的选择是添加A &lt;- matrix(A, ncol = 5); 或使用repmat 并返回一个矩阵?
    【解决方案2】:

    您正在尝试涉及多个大量模板化库的复合表达式。那可能会出错。我建议分段进行:

    1. 确保您将矩阵 A 传递给嵌入式 R

    2. 确保函数调用正常,检查结果。

    3. 重要提示:检查结果类型。矩阵应该可以正常返回。

    4. 将结果返回到 C++。

    5. 把它送到 Rcpp。

    6. 使用 RcppArmadillo 编组到达 Armadillo。

    原则上,这应该可行。魔鬼在细节中,一如既往。

    【讨论】:

    • 啊,很棒的建议,我用R.parseEval("str(A)"); 检查了结果类型,发现它把我的矩阵作为向量读取! num [1:25]
    • 同时 Romain 证明了我在 3. 中的预感是正确的。 C++ 仍然是一种强类型语言...
    猜你喜欢
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多