Return RcppArmadillo 向量作为 R 向量
Return RcppArmadillo vector as R vector
我无法弄清楚如何 return 将 RcppArmadillo colvec 作为标准 R 向量。我希望我可以通过 as<NumericVector>(wrap())
进行类型转换,但我最终还是得到了 R 矩阵的对象。这是一些代码来展示我的尝试(部分灵感来自 this previous question):
// [[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))
);
}
如果我查看输出,我会得到以下所有 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
您只需将 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
*/
这是一个 "feature"。在很早的某个时候,我们决定保留维度,因此向量总是作为具有一行或一列的矩阵返回。由于这个 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>
不过,只去除 R 侧的尺寸可能更有效。
这是一个老问题,但在搜索主题时它仍然会出现在第一行,所以我想分享另一个自版本 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
如果合适,您可以用 ROWVEC 或 ANYVEC 替换 #define 中的 COLVEC。
我无法弄清楚如何 return 将 RcppArmadillo colvec 作为标准 R 向量。我希望我可以通过 as<NumericVector>(wrap())
进行类型转换,但我最终还是得到了 R 矩阵的对象。这是一些代码来展示我的尝试(部分灵感来自 this previous question):
// [[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))
);
}
如果我查看输出,我会得到以下所有 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
您只需将 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
*/
这是一个 "feature"。在很早的某个时候,我们决定保留维度,因此向量总是作为具有一行或一列的矩阵返回。由于这个 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>
不过,只去除 R 侧的尺寸可能更有效。
这是一个老问题,但在搜索主题时它仍然会出现在第一行,所以我想分享另一个自版本 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
如果合适,您可以用 ROWVEC 或 ANYVEC 替换 #define 中的 COLVEC。