【问题标题】:Rcpp: transform matrix to vectorRcpp:将矩阵转换为向量
【发布时间】:2020-04-05 00:49:32
【问题描述】:

通常我想将二维矩阵从 Rcpp 转换为 R 中的向量,使用“as(m)”应该很简单,但是,我仍然从 R 中得到一个矩阵,我想知道为什么?我应该在 Rcpp 中手动删除 attr 吗?

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

【问题讨论】:

    标签: r rcpp


    【解决方案1】:

    我不确定我是否理解问题或尝试的答案。你仍然在这里返回矩阵。并且 Rcpp 对重塑和更高级的 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,它 确实 具有明确的 rowveccolvec 类型,后者被别名为 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 作为返回类型以不与colvecrowvec 冲突。您可以选择其中一个,但您可以返回答案。

    编辑 2: 根据下面的评论:如果你真的只是想重塑你已经拥有的内容,则不需要 Rcpp。只需核对 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> 
    

    【讨论】:

    • 如果坚持使用 rcpp,在操作的相关代码行添加 m.attr("dim") = R_NilValue; 似乎会转换为 vector 。这是一场等待发生的事故吗?
    • 不,这是R的设计matrixvector类型..与Rcpp一样工作!
    • @DirkEddelbuettel 我可以通过添加一行得到预期的结果:x.attr("dim") = R_NilValue,我可以这样做吗?
    • 正如我所说和展示的,你可以在 R 中做到这一点。那么为什么要在 C++ 中麻烦呢?但是,是的,如果您想 删除 维度,那么您将如何在 C++ 中执行此操作。请参阅Rcpp Gallery 网站上的尺寸介绍。
    【解决方案2】:

    感谢@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
    */
    

    【讨论】:

    • as&lt;&gt; 仍然错误/不需要。 NumericVector x(m); x,attr("dim") &lt;- R_NilValue;
    • 很有可能做NumericVector matrix2vector(NumericMatrix m, bool byrow=false){ if(byrow){ m = transpose(m); } m.attr("dim") = R_NilValue; return(m); }
    • @DirkEddelbuettel谢谢,它有效。最初“as”格式改编自 [这里] (teuder.github.io/rcpp4everyone_en/…) 的导师文档
    • as&lt;&gt;() 是一个非常有价值的关键组件,当您需要转换时需要它。在这里你没有。所以没有as&lt;&gt;()
    猜你喜欢
    • 1970-01-01
    • 2017-06-10
    • 2021-04-29
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 2012-12-24
    相关资源
    最近更新 更多