将RcppArmadillo矢量作为R向量返回

eks*_*oem 12 r rcpp

我无法弄清楚如何将RcppArmadillo colvec作为标准R矢量返回.我希望我可以进行类型转换,as<NumericVector>(wrap())但我仍然最终得到了R矩阵的对象.这里有一些代码来展示我尝试过的内容(部分受到前一个问题的启发):

// [[Rcpp::export]]                                                                                                                     
List testthis(NumericVector x) {
  arma::colvec y = x;
  arma::vec z = x;

  return List::create(Rcpp::Named("y1")=y,
                      Rcpp::Named("y2")=wrap(y),
                      Rcpp::Named("y3")=as<NumericVector>(wrap(y)),
                      Rcpp::Named("z1")=z,
                      Rcpp::Named("z2")=arma::trans(z),
                      Rcpp::Named("z3")=as<NumericVector>(wrap(z))
                      );
}
Run Code Online (Sandbox Code Playgroud)

如果我查看输出,我会得到以下所有R矩阵对象.我可以把它投射到R矢量吗?

> testthis(c(1:3))
$y1
     [,1]
[1,]    1
[2,]    2
[3,]    3

$y2
     [,1]
[1,]    1
[2,]    2
[3,]    3

$y3
     [,1]
[1,]    1
[2,]    2
[3,]    3

$z1
     [,1]
[1,]    1
[2,]    2
[3,]    3

$z2
     [,1] [,2] [,3]
[1,]    1    2    3

$z3
     [,1]
[1,]    1
[2,]    2
[3,]    3
Run Code Online (Sandbox Code Playgroud)

nru*_*ell 12

您可以将dim属性设置为NULL,因为矩阵几乎只是具有维度属性的常规向量.从C++方面看起来像这样:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
Rcpp::List testthis(Rcpp::NumericVector x) {
  arma::colvec y = x;
  arma::vec z = x;

  Rcpp::NumericVector tmp = Rcpp::wrap(y);
  tmp.attr("dim") = R_NilValue;

  Rcpp::List result = Rcpp::List::create(
    Rcpp::Named("arma_vec") = y,
    Rcpp::Named("R_vec") = tmp);

  return result;
}

/*** R

R> testthis(c(1:3))
# $arma_vec
#   [,1]
# [1,]    1
# [2,]    2
# [3,]    3
#
# $R_vec
#   [1] 1 2 3

R> dim(testthis(c(1:3))[[1]])
#[1] 3 1
R> dim(testthis(c(1:3))[[2]])
#  NULL

*/
Run Code Online (Sandbox Code Playgroud)


Dir*_*tel 8

这是一个"功能".在很早的时候我们决定保留尺寸,因此矢量总是以一行或一列的矩阵形式返回.由于这个API很久以前就建立了,现在很难改变,因为我们会破坏现有的代码.

感谢上面所有的变化.这是另一个有助于通过std::vector<double>:

R> cppFunction("std::vector<double> foo(arma::vec v) { 
+                               return as<std::vector<double> >(wrap(v)); }", 
+              depends="RcppArmadillo")
R> foo(c(5.5,6.6,7.42))
[1] 5.50 6.60 7.42
R> 
Run Code Online (Sandbox Code Playgroud)

然而,仅在R侧剥离尺寸可能更有效.


小智 6

这是一个老问题,但在搜索主题时它仍会在第一行弹出,所以我想分享另一个可能自版本0.7.960.1.0以来的选项.在#include和voilà之前插入适当的#define:

#define RCPP_ARMADILLO_RETURN_COLVEC_AS_VECTOR
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::vec testthis(arma::vec x) {
   return x+1;
}
/*** R
testthis(1:3)
*/

> testthis(1:3)
[1] 2 3 4
Run Code Online (Sandbox Code Playgroud)

如果合适,您可以通过ROWVEC或ANYVEC替换#define中的COLVEC.