Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert std::vector to Rcpp matrix

Tags:

r

rcpp

This is an Rcpp conversion related Q. I'm looking to convert a long std::vector into a Rcpp matrix object, but want to know if there is an easy conversion format. Naturally, you could loop over each element and fill an empty Rcpp matrix, but this seems error prone and possibly needless if a more convenient approach is possible.

The reason I'm asking is I would like to utilize OpenMP in some existing C++ code, but storing element in the Rcpp matrix object directly in an OpenMP loop doesn't appear to work well (whereas loading a std::vector object and converting to a matrix after the OpenMP loop is complete seems to be a decent approach to the problem).

Any help would be greatly appreciated!

like image 414
philchalmers Avatar asked Nov 08 '13 16:11

philchalmers


1 Answers

To expand on Dirk's answer; R matrices are really just vectors with a dim attribute set

> x <- 1
> y <- as.matrix(x)
> .Internal( inspect(x) )
@7f81a6c80568 14 REALSXP g0c1 [MARK,NAM(2)] (len=1, tl=0) 1 ## data
> .Internal( inspect(y) )
@7f81a3ea86c8 14 REALSXP g0c1 [NAM(2),ATT] (len=1, tl=0) 1 ## data
ATTRIB:
  @7f81a3e68e08 02 LISTSXP g0c0 [] 
    TAG: @7f81a30013f8 01 SYMSXP g1c0 [MARK,LCK,gp=0x4000] "dim" (has value) 
    @7f81a3ea8668 13 INTSXP g0c1 [NAM(2)] (len=2, tl=0) 1,1

Notice how the 'data' component of x and y are just REALSXPs, but you have this extra dim component on the matrix. Using this, we can easily convert a NumericVector to a matrix in Rcpp.

(Note: in the example below, I use SEXP in the attributes just so the conversions between types are explicit):

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
SEXP vec_to_mat(SEXP x_) {
  std::vector<double> x = as< std::vector<double> >(x_);
  /* ... do something with x ... */
  NumericVector output = wrap(x);
  output.attr("dim") = Dimension(x.size(), 1);
  return output;
}

/*** R
m <- c(1, 2, 3)
vec_to_mat(m)
*/

gives me

> m <- c(1, 2, 3)

> vec_to_mat(m)
     [,1]
[1,]    1
[2,]    2
[3,]    3

So, you can use the Dimension class and assign it to the dim attribute of a vector to make a matrix 'by hand' in Rcpp.

like image 164
Kevin Ushey Avatar answered Oct 17 '22 13:10

Kevin Ushey