C ++でRの機能を活用する方法

Rは、統計データ処理とグラフィックスのためのプログラミング言語であり、GNUプロジェクト©Wikipediaのフレームワークにおける無料のオープンソースコンピューティング環境です。



Rはあらゆる場面で膨大な数の統計アルゴリズムを収集しており、ネイティブソフトウェア環境からだけでなく、SPSS、Statistica、SAS、Wolfram Mathematicaなどの有名な数学パッケージでサポートされています。 Rをアプリケーションに統合するにはどうすればよいですか?

HabrahabrにはC ++でRを使用することに関する記事が既にありましたが、コードがGPL互換ライセンスで配布されている場合にのみ使用できる方法の1つに焦点を当てました。 しかし、それ以外の場合は解決策があります-Rserveパッケージを使用します。



サーブ



Rserveは、ライブラリにリンクしなくてもRの機能を使用できるTCP / IP / UNIXソケットサーバーです。 クライアントは、C / C ++、Java、PHPなどのさまざまな一般的な言語で実装されます。 LGPLの下で配布される顧客コード。



RとRserveをインストールします。

# sudo apt-get instal r-base # sudo R > install.packages("Rserve");
      
      





これで、Rserveを実行できます。

 # R CMD Rserve
      
      





デバッグモードもあります

 # R CMD Rserve.dbg
      
      





パラメータなしで起動すると、Rserveはデフォルトポート(6311)でTCP / IPサーバーモードで動作します。 UNIXソケットを使用するには、-RS-socketフラグを指定してRserveを実行します

 # R CMD Rserve --RS-socket "/home/zoberg/mysocket"
      
      





入力可能なフラグのリストを表示するには、次のように入力します

 # R CMD Rserve --help
      
      





C ++クライアント



C ++クライアントは4つのヘッダーファイルで構成されます: Rconnection.h (ここで動作するために必要なすべての広告)、 Rsrv.hconfig.h (Windowsでのみ必要)、 sisocks.h (クロスプラットフォームソケット)、1つのRconnection.cc 。 これらはすべてguthubの公式リポジトリから取得できます



それでは、主な操作のほとんどをカバーするデモを見てみましょう



 /// main.cpp #include <iostream> using std::cout; #define MAIN // c  sisocks.h #define SOCK_ERRORS // verbose socket errors #include "sisocks.h" #include "Rconnection.h" //     C++ API int main(int argc, char **argv) { initsocks(); //    Win32 -     unix //     Rserve. //     - "127.0.0.1", 6311. //    unix sockets,     : // Rconnection *rc = new Rconnection("/home/zoberg/mysocket", -1); Rconnection *rc = new Rconnection(); int i=rc->connect(); if (i) { char msg[128]; sockerrorchecks(msg, 128, -1); printf("unable to connect (result=%d, socket:%s).\n", i, msg); return i; } double d[6] = { 1.5, 2.4, 5.6, -1.2, 0.6, 1.7 }; //      "a"  R Rdouble *rd = new Rdouble(d, 6); rc->assign("a", rd); delete rd; //   "b"  2 x 3     b * t(b) Rdouble *x = (Rdouble*) rc->eval("b<-matrix(a,2); b%*%t(b)"); if (x) { //    ,    cout << x << "\n"; //       Rinteger *dim = (Rinteger*) x->attribute("dim"); if (dim) cout << dim->intAt(0) << " by " << dim->intAt(1) << " matrix\n"; //    ( ) double *d = x->doubleArray(); int i=0, ct = x->length(); while (i < ct) { cout << d[i++] << " "; } cout << "\n"; //   delete x; } //      i  R int ia[6] = { 1, 4, 6, 3, 5 , 2 }; Rinteger *ri = new Rinteger(ia, 6); rc->assign("i", ri); delete ri; //   —      , //       1936   //      . //      R,   Rvector *iris = (Rvector*) rc->eval("data(iris); iris"); if (!iris) { cout << "oops! couldn't get iris data\n"; delete rc; return 0; } //         (sepal width) - //      Rserve,         Rdouble *sw = (Rdouble*) iris->byName("Sepal.Width"); double *swd = sw->doubleArray(); // and print it ... { int i=0, ct=sw->length(); while (i<ct) { cout << swd[i++] << " "; } cout << "\n"; } //    ,   iris, //  sw  . delete iris; //   .   . delete rc; }
      
      





メモリ管理に関する注意:必要なすべてのメモリは、「eval」を呼び出すときに暗黙的に作成されるRmessageオブジェクトによって割り当てられます。 このオブジェクトの所有者はRexpであり、これはevalによって返されます(メインオブジェクトと呼びましょう)。 メイン以外のRexpをリリースすることはできません! メインRexpに関連付けられている他のRexpは、メインRexpのリリース後に無効になります。 また、メインRexpを解放すると、すべてのポインターが無効になります(たとえば、doubleArray()メソッドによって返されます)。



コンパイルする

 # g++ -c Rconnection.cc # g++ Rconnection.o main.cpp -o RExample -lcrypt
      
      





そして走る

 # ./RExample Rdouble[4] 2 by 2 matrix 33.97 -2.1 -2.1 10.09 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 3.7 3.4 3 3 4 4.4 3.9 3.5 3.8 3.8 3.4 3.7 3.6 3.3 3.4 3 3.4 3.5 3.4 3.2 3.1 3.4 4.1 4.2 3.1 3.2 3.5 3.6 3 3.4 3.5 2.3 3.2 3.5 3.8 3 3.8 3.2 3.7 3.3 3.2 3.2 3.1 2.3 2.8 2.8 3.3 2.4 2.9 2.7 2 3 2.2 2.9 2.9 3.1 3 2.7 2.2 2.5 3.2 2.8 2.5 2.8 2.9 3 2.8 3 2.9 2.6 2.4 2.4 2.7 2.7 3 3.4 3.1 2.3 3 2.5 2.6 3 2.6 2.3 2.7 3 2.9 2.9 2.5 2.8 3.3 2.7 3 2.9 3 3 2.5 2.9 2.5 3.6 3.2 2.7 3 2.5 2.8 3.2 3 3.8 2.6 2.2 3.2 2.8 2.8 2.7 3.3 3.2 2.8 3 2.8 3 2.8 3.8 2.8 2.8 2.6 3 3.4 3.1 3 3.1 3.1 3.1 2.7 3.2 3.3 3 2.5 3 3.4 3
      
      





できた! Rインターフェイスの詳細については、Rconnection.hを参照してください。



Rserv.conf



構成ファイルRserv.confについて少し説明します。 Rserveの開始時にRコードを実行する興味深い機会を提供します。 デフォルトの構成ファイルは/etc/Rserv.confで検索されますが、Rserveの起動時に--RS-confフラグを使用して別のパスを指定することもできます。 Rserv.confには次のオプションが含まれる場合があります。



workdir [/tmp/Rserv]



pwdfile [none=disabled]



remote enable|disable [disable]






auth required|disable [disable]





plaintext enable|disable [disable]





fileio enable|disable [enable]





interactive yes|no [yes] (since 0.6-2)







( 0.1-9):

socket [none=disabled]

port [6311]

maxinbuf [262144]



( 0.3):

maxsendbuf [0=unlimited]

uid [none]

gid [none]

su now|server|client [none] (since 0.6-1)








( 0.3-16):

source

eval



( 0.5 unix):

chroot [none]

sockmod [0=default]

umask [0]



( 0.5-3):

encoding native|utf8|latin1 [native]








Rserve C++ , . , - .



PS load-balancer Rserve: RSproxy .



UPDATE: Windows Ws2_32.lib.























































All Articles