在Rcpp中选择不连续的子矩阵

时间:2011-12-08 17:36:50

标签: c++ r rcpp

我正在尝试使用非连续切片选择Rcpp中的子矩阵。等效的R代码是

> xx = matrix(0,nrow=10,ncol=8)
> xx[,c(1,3,4)]
      [,1] [,2] [,3]
 [1,]    0    0    0
 [2,]    0    0    0
 [3,]    0    0    0
 [4,]    0    0    0
 [5,]    0    0    0
 [6,]    0    0    0
 [7,]    0    0    0
 [8,]    0    0    0
 [9,]    0    0    0
[10,]    0    0    0

在Rcpp,我试图做

Rcpp::NumericMatrix xx(10,8);
Rcpp::NumericMatrix aa = xx(Rcpp::Range(0,9), Rcpp::NumericVector::create(1,3,4));

然而,这给出了

error: no match for call to '(Rcpp::NumericMatrix) (Rcpp::Range, Rcpp::Vector<14>)'
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:126: note: candidates are: typename Rcpp::Vector<RTYPE>::Proxy Rcpp::Matrix<RTYPE>::operator()(const size_t&, const size_t&) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:132: note:                 typename Rcpp::Vector<RTYPE>::Proxy Rcpp::Matrix<RTYPE>::operator()(const size_t&, const size_t&) const [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:142: note:                 Rcpp::MatrixRow<RTYPE> Rcpp::Matrix<RTYPE>::operator()(int, Rcpp::internal::NamedPlaceHolder) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:146: note:                 Rcpp::MatrixColumn<RTYPE> Rcpp::Matrix<RTYPE>::operator()(Rcpp::internal::NamedPlaceHolder, int) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:150: note:                 Rcpp::SubMatrix<RTYPE> Rcpp::Matrix<RTYPE>::operator()(const Rcpp::Range&, const Rcpp::Range&) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:154: note:                 Rcpp::SubMatrix<RTYPE> Rcpp::Matrix<RTYPE>::operator()(Rcpp::internal::NamedPlaceHolder, const Rcpp::Range&) [with int RTYPE = 14]
/opt/local/lib/R/library/Rcpp/include/Rcpp/vector/Matrix.h:158: note:                 Rcpp::SubMatrix<RTYPE> Rcpp::Matrix<RTYPE>::operator()(const Rcpp::Range&, Rcpp::internal::NamedPlaceHolder) [with int RTYPE = 14]

这可能在Rcpp吗?

3 个答案:

答案 0 :(得分:6)

NumericMatrix的帮助文件:http://dirk.eddelbuettel.com/code/rcpp/html/classMatrix.html

它表明没有方法可以使用Range和NumericVector,只有两个范围或“_”和范围......所以没有直接的方法来选择非连续的切片......

答案 1 :(得分:6)

以下是我的表现:

library(inline)

testSlice = cxxfunction(signature(r_mat='int', r_cols='int'), body = 
'
NumericMatrix mat (r_mat);
NumericVector cols (r_cols);

NumericMatrix matslice (mat.nrow(), cols.size());

for (int i=0; i<cols.size(); i++) {
  matslice(_,i) = mat(_, cols(i)-1);
}

return(matslice);
'
, plugin='Rcpp')
> xx = matrix(sample(10, 10*10, replace=T), nrow=10)
> xx
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    6    7    9    8    2    6    1    8   10     8
 [2,]    5    6    9    5    1    5    2    7   10     3
 [3,]    9    5    1   10    8   10   10    1    2     7
 [4,]    2    7    1    4    5    1    8    2   10     9
 [5,]    6    6    9    8    3    1    2   10    2     1
 [6,]    4    6    7    9    7    5    4    7   10    10
 [7,]   10   10    8    8   10    7   10    4    6     3
 [8,]    6    3   10    6    3    2    5    4    1    10
 [9,]    8    7    2    7    9    7    7    8    3    10
[10,]    5    4    5    4    4    8   10    1    5     4

> testSlice(xx, c(2,5,6))
      [,1] [,2] [,3]
 [1,]    7    2    6
 [2,]    6    1    5
 [3,]    5    8   10
 [4,]    7    5    1
 [5,]    6    3    1
 [6,]    6    7    5
 [7,]   10   10    7
 [8,]    3    3    2
 [9,]    7    9    7
[10,]    4    4    8

答案 2 :(得分:0)

你可以这样,不是吗?可能你必须调整参数和返回类型

mat submat_cols(mat X, uvec idx) {
    mat y = X.cols(idx);
    return y;
}

这个问题也与讨论here有关。我刚刚发布了三个基准测试解决方案。它是关于基于逻辑向量对矩阵进行子集化。但这是一个类似的问题 xx[,c(1:8) %in% c(1,3,4)]代替xx[,c(1,3,4)]会产生相同的结果。无论如何,为这些东西提供糖解决方案真的很棒。