Search code examples
rrcpp

Convert arma:vec to NumericVector in Rcpp


I try to use the quantile function in RcppArmadillo, however, in the tutorial, the output of quantile function is arma::vec (The class of output in R is "matrix" "array").

quantile function in arma

I want to convert it to NumericVector. I have tried with the codes following:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;


// quantile function
// [[Rcpp::export]]
NumericVector quantile_f(vec V, vec P) {
  vec Q = quantile(V, P);
  NumericVector Q_output = as<NumericVector>(wrap(Q));
  return (Q_output);
}

I followed the link to do this. But I still get class in R = "matrix" "array".

Output of my function in R

Can anyone help with this? Thank!


Solution

  • (Please don't post images. Links to the documentation are preferred.)

    You don't need to convert it:

    Code

    // force return as a vector rather than single column matrix
    #define RCPP_ARMADILLO_RETURN_ANYVEC_AS_VECTOR
    
    #include <RcppArmadillo.h>
    // [[Rcpp::depends(RcppArmadillo)]]
    
    // [[Rcpp::export]]
    arma::vec quantile_f(arma::vec V, arma::vec P) {
        return arma::quantile(V, P);
    }
    
    /*** R
    set.seed(123)
    quantile_f(rnorm(1000), c(0, 0.25, 0.5, 0.75, 1.0))
    */
    

    Output

    > Rcpp::sourceCpp("~/git/stackoverflow/73979000/answer.cpp")
    
    > set.seed(123)
    
    > quantile_f(rnorm(1000), c(0, 0.25, 0.5, 0.75, 1.0))
    [1] -2.80977468 -0.62874241  0.00920964  0.66478787  3.24103993
    > 
    

    Internally, of course, the equivalent conversion happens as the Armadillo vectors becomes the C++ variant of an R vector which is our Rcpp::NumericVector. But the existing code is nice enough to automate this for you.

    Edit One can also explicitly reset the dimension attribute from an n by one matrix to a vector of length one:

    // [[Rcpp::export]]
    Rcpp::NumericVector quantile_f2(arma::vec V, arma::vec P) {
        arma::vec v = arma::quantile(V, P);
        Rcpp::NumericVector w = Rcpp::NumericVector(Rcpp::wrap(v));
        w.attr("dim") = static_cast<int>(v.n_elem);
        return w;
    }