Reputation: 375
Generally I want to transform a 2-D matrix from Rcpp to a vector in R, it should be very simple by using "as(m)", however, I still get a matrix from R, I wonder why? SHould I remove the attr manually in Rcpp?
#include <Rcpp.h>
#include <string>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector matrix2vector(NumericMatrix m, const bool byrow=false){
NumericVector x;
if(byrow){
Rcout<< "warning: default by column\n";
m = transpose(m);
x = as<NumericVector>(m);
}else{
x = as<NumericVector>(m);
}
return(x);
}
/*** R
m=matrix(1:15,5,3)
matrix2vector(m,byrow=T)
*/
Upvotes: 2
Views: 1540
Reputation: 375
Thanks to @user2957945 and @Dirk Eddelbuettel.
What I want is as below:
#include <Rcpp.h>
#include <string>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector matrix2vector(NumericMatrix m, const bool byrow=false){
NumericVector x;
if(byrow){
Rcout<< "warning: default by column\n";
m = transpose(m);
}
NumericVector x(m);
x.attr("dim") = R_NilValue;
return(x);
}
/*** R
m=matrix(1:15,5,3)
matrix2vector(m,byrow=T)
# [1] 1 6 11 2 7 12 3 8 13 4 9 14 5 10 15
*/
Upvotes: 2
Reputation: 368181
I am not sure I understand the question, or the attempted answer. You are still returning matrices here. And Rcpp has limited support for reshaping and more advanced Matrix operations.
A slighly simplified version of your code:
Code#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector matrix2vector(NumericMatrix m, const bool byrow=false){
if (byrow){
Rcout << "warning: default by column\n";
m = transpose(m);
}
return NumericVector(m);
}
/*** R
m <- matrix(1:15,5,3)
print(matrix2vector(m, byrow = TRUE))
print(matrix2vector(m, byrow = FALSE))
*/
Output
R> Rcpp::sourceCpp("~/git/stackoverflow/61036707/question.cpp")
R> m <- matrix(1:15,5,3)
R> print(matrix2vector(m, byrow = TRUE))
warning: default by column
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 6 7 8 9 10
[3,] 11 12 13 14 15
R> print(matrix2vector(m, byrow = FALSE))
[,1] [,2] [,3]
[1,] 1 6 11
[2,] 2 7 12
[3,] 3 8 13
[4,] 4 9 14
[5,] 5 10 15
R>
All you are executing here, really, is a transpose.
I would try RcppArmadillo which does have explicit rowvec
and colvec
types, with the latter being aliased to vec
. I would have to check what it suggest in terms of reshaping "rows by columns" elements into a rows by columns vector.
Edit: Indeed (as so often) easier in RcppArmadillo.
Code#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat matrix2vector(arma::mat m, const bool byrow=false){
if (byrow) {
return m.as_row();
} else {
return m.as_col();
}
}
/*** R
m <- matrix(1:15,5,3)
print(matrix2vector(m, byrow = TRUE))
print(matrix2vector(m, byrow = FALSE))
*/
Output
R> Rcpp::sourceCpp("~/git/stackoverflow/61036707/answer.cpp")
R> m <- matrix(1:15,5,3)
R> print(matrix2vector(m, byrow = TRUE))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
[1,] 1 6 11 2 7 12 3 8 13 4 9 14 5 10 15
R> print(matrix2vector(m, byrow = FALSE))
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
[5,] 5
[6,] 6
[7,] 7
[8,] 8
[9,] 9
[10,] 10
[11,] 11
[12,] 12
[13,] 13
[14,] 14
[15,] 15
R>
Note that I am using arma::mat
as the return type to not conflict with either colvec
or rowvec
. You could pick either but then you could not return the answer.
Edit 2: And per the comment below: if you really just want to reshape content you already have there is no need for Rcpp. Just nuke the dim
attribute. Works at the R (and C++ if you want) level:
R> m
[,1] [,2] [,3]
[1,] 1 6 11
[2,] 2 7 12
[3,] 3 8 13
[4,] 4 9 14
[5,] 5 10 15
R> dim(m)
[1] 5 3
R> dim(m) <- NULL
R> m
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
R>
Upvotes: 4