R cpp: преобразовать матрицу в вектор - PullRequest
1 голос
/ 05 апреля 2020

Как правило, я хочу преобразовать двумерную матрицу из R cpp в вектор в R, это должно быть очень просто, используя "as (m)", однако, я все еще получаю матрицу из R, интересно Почему? Должен ли я удалить attr вручную в R cpp?

#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)
*/

Ответы [ 2 ]

3 голосов
/ 05 апреля 2020

Я не уверен, что понимаю вопрос или попытку ответа. Вы все еще возвращаете матрицы здесь. И R cpp имеет ограниченную поддержку для изменения формы и более продвинутых операций Matrix.

Немного упрощенная версия вашего кода:

Код
#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))
*/
Вывод
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> 

На самом деле все, что вы выполняете здесь, это транспонирование.

Я бы попробовал RcppArmadillo который имеет , имеет явные типы rowvec и colvec, причем последний имеет псевдоним vec. Мне бы пришлось проверить, что он предлагает с точки зрения преобразования элементов «строк по столбцам» в вектор строк по столбцам.

Редактировать: Действительно (как это часто бывает) проще в RcppArmadillo.

Код
#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))
*/
Вывод
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> 

Обратите внимание, что я использую arma::mat в качестве типа возврата, чтобы не конфликтовать с colvec или rowvec. Вы можете выбрать любой из них, но тогда вы можете не вернуть ответ.

Редактировать 2: И в соответствии с комментарием ниже: если вы действительно просто хотите изменить содержание, вы уже у нас нет необходимости в R cpp. Просто уничтожьте атрибут dim. Работает на уровне R (и C ++, если хотите):

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> 
1 голос
/ 05 апреля 2020

Спасибо @ user2957945 и @Dirk Eddelbuettel.

Что я хочу, это как показано ниже:

#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
*/
...