我正在尝试使用非连续切片选择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吗?
答案 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)]
会产生相同的结果。无论如何,为这些东西提供糖解决方案真的很棒。