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.h 、 config.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.