2015-09-15 19 views
6

Ich habe Probleme herauszufinden, wie man ein RcppArmadillo colvec als Standard-R-Vektor zurückgibt. Ich hatte gehofft, ich könnte durch as<NumericVector>(wrap() tippen, aber ich habe immer noch mit Objekten dort sind R-Matrizen. Hier ist ein Stück Code, um zu zeigen, was ich versucht habe (zum Teil durch this previous question inspiriert):Return RcppArmadillo Vektor als R Vektor

// [[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)) 
        ); 
} 

und wenn ich am Ausgang aussehen erhalte ich die folgende, die alle R-Matrix-Objekte sind. Kann ich es in R-Vektoren umwandeln?

> 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 

Antwort

9

Sie können einfach stellen Sie das dim Attribut NULL, da Matrizen so ziemlich nur regelmäßige Vektoren mit einem dimensionalen Attribute sind. Von der C++ Seite sieht es so aus:

#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

Das ist auch gut - schön. –

+1

Sowohl @russels als auch Dirks Antworten haben mir bei meiner Frage geholfen. Da sie etwas andere (aber gültige) Lösungen bieten, habe ich eine Münze geworfen, wer die Antwort bekommen sollte. Danke beiden! – ekstroem

5

Es ist ein "Feature". Irgendwann zu einem sehr frühen Zeitpunkt haben wir uns entschieden, Dimensionen beizubehalten, so dass Vektoren immer als Matrizen mit einer Zeile oder Spalte zurückkommen. Da diese API schon vor einiger Zeit eingeführt wurde, ist es jetzt schwierig, sie zu ändern, da wir bestehenden Code brechen würden.

Kudos zum Ausprobieren aller oben genannten Variationen. Hier ist eine andere, die über std::vector<double> indem Sie hilft:

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> 

Es ist wahrscheinlich effizienter, nur die Dimension, obwohl auf der R-Seite abzustreifen.

1

Dies ist eine alte Frage, aber es erscheint immer noch in den ersten Zeilen bei der Suche nach dem Thema, also möchte ich eine andere Option teilen, die seit der Version 0.7.960.1.0 möglich ist. Legen Sie eine entsprechende #define vor #include und voilà:

#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 

Sie können COLVEC in #define von ROWVEC oder ANYVEC gegebenenfalls ersetzen.