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!
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 REALSXP
s, 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With