矩阵的列排序

Column-wise ordering of matrix

我是 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));
}

不确定为什么要在此处对索引进行排序,因为与 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