web-dev-qa-db-ja.com

Rcppでベクターのリストを作成するにはどうすればよいですか?

私はRcppモジュールを書いていますが、RcppResultSetリストの1つの要素として、要素がベクトルであるリストを返したいと思います。例:.Call("myfunc")$fooは次のようになります。

[[1]]
[1] 1

[[2]]
[1] 1 1

[[3]]
[1] 1 1 1

(正確な数はここでは重要ではありません)。問題は、これを行う正しいRcppの方法がわからないことです。 vector<vector<int> >を渡そうとしましたが、これは最初のベクトルの長さを幅として黙って取得することによって行列を作成します(行列が不規則であっても!)。 RcppListを作成しようとしましたが、さまざまなオブジェクト(RcppVectorなど)をSEXPsに安全にキャストするのに苦労しています。

Rcppのベクトルのリストなど、複雑な構造を処理するためのベストプラクティスに関するヒントはありますか?

30
Jonathan Chang

[ここでこれを見るのはうれしいですが、Romainと私は一般的に質問のために rccp-devel リストをお勧めします。プロジェクトはまだそれほど大きくないので、ウェブ全体に質問を散らばらせる必要があるので、今後そこに投稿してください。 ]

RcppResultSetは古いclassicAPIの一部ですが、newと呼ばれるものに多くの作業が費やされていますAPI(0.7。*リリース以降)。現在の CRANのRcppページ とビネットのリスト-6とカウントを見てください。

新しいAPIを使用すると、次のようなものが返されます。

_return Rcpp::List::create(Rcpp::Named("vec") = someVector,
                          Rcpp::Named("lst") = someList,
                          Rcpp::Named("vec2") = someOtherVector);
_

オールインワンステートメント(そしておそらく明示的なRcpp::wrap()呼び出しを使用)、 [〜#〜] r [〜#〜] で何を作成するか

_list(vec=someVector, lst=someList, vec2=someOtherVector)
_

また、_Rcpp::List_は、リストのリストのリストを実行できるはずです...これに対する単体テストがあるかどうかはわかりませんが、500以上の単体テストには多数の例があります。

たまたま、私はここ数日、多くの RQuantLib コードを従来のAPIから新しいAPIに変換するのに費やしました。これは、バージョン0.8.3の Rcpp がリリースされたら(できれば数日以内に)リリースされる可能性があります。それまでの間、 RQuantLib SVNアーカイブ をご覧ください。

43

私はDirkのソリューションの圧縮されたバリエーションを使用する傾向があります:

using namespace Rcpp ;
return List::create( 
   _["vec"]  = someVector, 
   _["lst"]  = someList, 
   _["vec2"] = someOtherVector
 ) ;

また、元の質問に戻るには、vector< vector<int> >は、行列ではなく整数ベクトルのリストにラップする必要があります。見る:

require( Rcpp )
require( inline )
require( RUnit )

fx <- cxxfunction( , '

    std::vector< std::vector<int> > v ;

    std::vector<int> x1(1) ; v.Push_back( x1 );
    std::vector<int> x2(2) ; v.Push_back( x2 );
    std::vector<int> x3(3) ; v.Push_back( x3 );

    return wrap( v ) ;

', plugin = "Rcpp" ) 

私は得る:

> fx() 

[[1]]
[1] 0

[[2]]
[1] 0 0

[[3]]
[1] 0 0 0
24
Romain Francois