2015-09-15 11 views
6

RcppArmadillo colvecを標準Rベクターとして返す方法を知りません。私はas<NumericVector>(wrap()を介して型キャストできることを願っていましたが、まだオブジェクトにはR個の行列があります。ここで私が試したものを表示するコードのビットは、(部分的にthis previous questionに触発さ)です:RcppArmadilloベクターを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)) 
        ); 
} 

と私は出力を見れば、私は、すべての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 

答えて

9

行列はかなり次元の属性を持つ普通のベクトルですので、あなたはただ、NULLdim属性を設定することができます。 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 

*/ 
+1

これもいいですよね。 –

+1

@ nrussellとDirkの両方の回答が私の質問に私を助けました。彼らはわずかに異なる(しかし、有効な)ソリューションを提供するので、誰が回答クレジットを得なければならないかについてコインを裏返した。両方に感謝! – ekstroem

5

「機能」です。非常に早い時期に次元を保持することに決めました。そのため、ベクトルは常に1つの行または列を持つ行列として戻ってきました。このAPIはかなり前に確立されていたので、既存のコードを破るように変更するのは現在難しいです。

上記のすべてのバリエーションを試してください。

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側の次元を取り除くために、おそらく、より効率的である:ここではstd::vector<double>を経由して行くことによって、助けている別のです。

1

これは古い質問ですが、件名を検索するときに最初の行で表示されるため、バージョン0.7.960.1.0以降で別のオプションを使用したいと考えています。 #include出来上がり前に適切なの#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を置き換えることができます。

関連する問題