矩阵的逐列排序

时间:2018-01-16 05:10:55

标签: c++ r sorting rcpp armadillo

我是 RcppArmadillo 的新手。我想知道如何通过给定向量的索引来制作列式有序矩阵。我知道如何在 R 中做到这一点,但在RcppArmadillo中它不起作用。例如,在 R 中,

aa = c(2,4,1,3)
# [1] 2 4 1 3
bb = cbind(c(1,5,4,2),c(3,1,0,8))
#      [,1] [,2]
# [1,]    1    3
# [2,]    5    1
# [3,]    4    0
# [4,]    2    8

尝试使用 R 进行子集化:

cc = bb[aa,]
#      [,1] [,2]
# [1,]    5    1
# [2,]    2    8
# [3,]    1    3
# [4,]    4    0

我使用RcppArmadillo尝试了以下内容:

#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
List example(arma::vec aa,arma::mat bb){

  int p = bb.n_rows;
  int n = aa.size();

  arma::uvec index_aa=sort_index(aa);;

  List cc(n);
  for(int it=0; it<p; it++){
    cc(it) = bb.each_col();
  }

  return List::create(cc);
}

#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
List example(arma::vec aa,arma::mat bb){

  arma::uvec index_aa=sort_index(aa);

  return List::create(bb.elem(index_aa));
}

1 个答案:

答案 0 :(得分:2)

不确定为什么要在此处对索引进行排序,因为与bb[aa,]相比,这会导致引入新订单。

无论如何,这里的想法是使用.rows()索引进行子集,这需要uvecunsigned integer向量。由于aa包含 R 索引,我们可以将它们从 R 转换为 C ++ ,方法是减去1以从1开始索引系统到基于0的索引系统。

#include <RcppArmadillo.h>

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::mat example_subset(arma::uvec aa, arma::mat bb){

  // Convert to a C++ index from R (1 to 0-based indices)
  aa = aa - 1;

  return bb.rows(aa);
}

测试代码:

aa = c(2, 4, 1, 3)
bb = cbind(c(1, 5, 4, 2), c(3, 1, 0, 8))
cpp_cc = example_subset(aa, bb)
r_cc = cbind(c(5,2,1,4),c(1,8,3,0))
all.equal(cpp_cc, r_cc)
# [1] TRUE