Location : Home > Softwares > R
Title : Using the R (D)COM Server
Toolbox Logo

Using the R (D)COM Server

トラブルシューティング

 最初に COM オブジェクトの .Init() を呼び出したときに何か悪いことが起これば .GetErrorText() を用いてエラー情報を取得すること。

"installation problem: unable to load connector"

 R プロキシライブラリがロードできない。これらのエラーの原因として考えられるのは以下の通り。

  • 環境変数 %R_HOME% が R がインストールされていないディレクトリを指しており、
  • R インストールに対応するレジストリキーが R のインストールフォルダを指しており、
  • rproxy.dll 及び R.dll%PATH% にない。

 CRAN からコンパイル済みのバイナリをダウンロードしてこれをインストールしたのに間違った場合である。セットアッププログラムを使って R を再インストールすること。何が悪いかについては dbgview をダウンロードして確認すること。
 自身で R をコンパイルした場合には %R_HOME%\bin\rproxy.dll を確認し、レジストリキー HKEY_LOCAL_MACHINE\Software\R-core\R\InstallPath が正しくインストールフォルダを指しているか確認すること。

"installation problem: invalid connector library"

 おそらく R プロキシライブラリにダメージ。COM サーバの本バージョンでは R >= 2.2. が必要。

"installation problem: interpreter interface version mismatch"

 R プロキシライブラリのバージョンが正しくない。COM サーバの本バージョンでは R >= 2.2. が必要。

"installation problem: interpreter version mismatch"

 R のバージョンが正しくない。COM サーバの本バージョンでは R >= 2.2. が必要。

 .Init() を呼び出したときにメッセージボックスが表示されればベースライブラリが見つけられなかったことを示す。その場合は R_HOME をインストールフォルダに設定すればよい。このような場合はわずかであろう。
 自身でインストールの問題が解決できなかった場合は R COM メーリングリストでヘルプを確認してみること。 R COM サーバ(または R COM 接続モジュールの他の部分)を使うのであれば参加しておくとよい。
 全ての関数は上に示した状況と対応するエラーコードを返す。このエラーコードは VB または VBA における Err.Number を確認することで取得することができる関数の返り値である。以下の表はエラーコードのリストである。

定義DecimalHexadecimal
SCN_E_INVALIDARG-2147221503 0x80040001
SCN_E_INVALIDFORMAT-2147221502 0x80040002
SCN_E_NOTIMPL-2147221501 0x80040003
SCN_E_UNKNOWN-2147221500 0x80040004
SCN_E_INITIALIZED -2147221499 0x80040005
SCN_E_NOTINITIALIZED -2147221498 0x80040006
SCN_E_INVALIDSYMBOL-2147221497 0x80040007
SCN_E_PARSE_INVALID-2147221496 0x80040008
SCN_E_PARSE_INCOMPLETE-2147221495 0x80040009
SCN_E_UNSUPPORTEDTYPE -2147221494 0x8004000A
SCN_E_EVALUATE_STOP-2147221493 0x8004000B
SCN_E_INVALIDINTERFACEVERSION-2147221488 0x80040010
SCN_E_INVALIDINTERPRETERVERSION -2147221487 0x80040011
SCN_E_INTERFACENOTFOUND -2147221486 0x80040012
SCN_E_LIBRARYNOTFOUND -2147221485 0x80040013
SCN_E_INVALIDLIBRARY -2147221484 0x80040014
SCN_E_INITIALIZATIONFAILED -2147221483 0x80040015
SCN_E_INVALIDCONNECTORNAME -2147221482 0x80040016
SCN_E_INVALIDINTERPRETERSTATE -2147221481 0x80040017
SCN_E_FATALBACKEND -2147221472 0x80040020

COM サーバを使う
(Visual Basic におけるサンプルコード)

  1. サーバオブジェクトを取得


    dim x as StatConnector
    set x = new StatConnector

     エラーハンドラをインストール。


    on error goto error_handler

  2. R を起動。


    x.Init ("R")

  3. R を利用。


    x.SetSymbol ("symname",value)

    または


    y = x.GetSymbol ("symname")

    または


    y = x.Evaluate ("expression")

    または


    x.EvaluateNoReturn ("expression")

  4. R を停止。


    x.Close

  5. エラーハンドラ


    error_handler:
    MsgBox x.GetErrorText,"R Server Error"

     要請する情報を特定する識別子(StatConnectorSrv.idlInformationType を見よ)を渡して x.GetServerInformation を呼び出すことで COM サーバに関する情報を取得することができる。x.GetConnectorInformation または R インタプリタ自身で x.GetインタープリタInformation を用いれば プロキシ dll に関する情報を取得できる。

COM サーバを使う
(Python におけるサンプルコード)

 Python で COM を利用するには Python for Windows extensions (http://starship.python.net/crew/mhammond/ で入手可能)がインストールされていなければならない。
 以下のコードを提供してくれた Dominic Barraclough (mailto:Dominic_Barraclough@urmc.rochester.edu) に感謝する。
 Python を起動した後、以下のように R と Python の間で通信を行う。


>>> from win32com.client import Dispatch
>>> sc=Dispatch("StatConnectorSrv.StatConnector")
>>> sc.Init("R")
>>> print(sc.Evaluate("2+2"))
4.0 # COMMENT- R can do arithmetic and can tell python about it!
>>>

COM サーバを使う
(APL におけるサンプルコード)

 このセクションは Grant Kilvington (mailto:gkilvington@edsellkilvington.com.au) の貢献による。

 私(訳注;このコードの筆者)は APL で R(D)Com を使っている。以下の説明が役に立てばうれしい。ここで利用している例は John Maindonald and John Braun 著・"Data Analysis and Graphics using R, An Example-based Approach" から採っている。

 まず R(D)COM と通信するための関数を持つ APL ワークスペースをロードする。ユーザが APL フォントを使うことは難しいし、他の言語と同様に用いることを目指して関数を記述しているからである。
 それから Rstart を起動して R を初期化する。これにより 'StatConnectorSrv.StatConnector' インスタンスを生成し、これにメソッド 'Xinit' を適用する。これで R はサーバとして利用可能である。
 次に RExec 'library(DAAG)' を実行してライブラリ "DAAG" をロードする。
 RExec は 'EvaluateNoReturn' (左引数がない場合)または 'Evaluate' (左引数がある場合)を用いる関数である。APL セッションに返す結果が欲しいか否かで異なる関数を用意した。
 次にコマンド RExec 'data(roller)' を実行してデータセット "roller" をロードする。1 RExec 'ls()' (<dummy> 左引数 であることに注意すること) を実行することで R サーバにデータを送り、 APL セッションに "roller" を返す。
 APL における値を確認するには(weight が与えられていれば) 1 RExec 'as.vector(roller$weight)' を実行し、weight (APL セッションでの変数)を確認すると以下のように値を見ることができる。

1.9 3.1 3.3 4.8 5.3 6.1 6.4 7.6 9.8 12.4

 APL 記号では左矢印で参照することができる。以降では単に <- コンストラクトを用いる。同様にデプレッションは depression <- 1 RExec 'as.vector(roller$depression)' で生成できる。

2 1 5 5 20 20 23 10 30 25

 weight に対しデプレッションの単回帰は以下のように計算できる。

RExec 'roller.lm <- lm(depression ~ weight, data=roller)'

 1 RExec 'as.vector(roller.lm$residuals)' で APL に値を返す。

0.9796694804 5.179764594 1.71311378  5.713232672 7.953394365 5.819997622 8.019973844 8.18012127  5.953037689 5.980501724

 1 RExec 'as.vector(roller.lm$coefficients)' は以下の値を返す。

2.087147783 2.666745928

 過剰な精度で申し訳ない。APL においては大きな負の値は数値である。- の記号は演算子である。
 さて行列のとして結果を取得できる。

{transpose} 1 RExec 'as.matrix(roller)'
  1.9  2
  3.1  1
  3.3  5
  4.8  5
  5.3 20
  6.1 20
  6.4 23
  7.6 10
  9.8 30
 12.4 25

 R オブジェクトを生成し、APL で取得することができる。

RExec 'dframe<-data.frame(roller,fitted.value=predict(roller.lm), residual=resid(roller.lm))'

{transpose} 1 RExec 'as.matrix(dframe)'
  1.9  2  2.97966948   0.9796694804
  3.1  1  6.179764594  5.179764594
  3.3  5  6.71311378   1.71311378
  4.8  5 10.71323267   5.713232672
  5.3 20 12.04660564   7.953394365
  6.1 20 14.18000238   5.819997622
  6.4 23 14.98002616   8.019973844
  7.6 10 18.18012127   8.18012127
  9.8 30 24.04696231   5.953037689
 12.4 25 30.98050172   5.980501724

 またはベクトルとしてフレームの一部を取得することもできる。

1 RExec 'as.vector(dframe$fitted.value)'
  2.97966948 6.179764594  6.71311378 10.71323267 12.04660564 14.18000238 14.98002616 18.18012127 24.04696231 30.98050172

1 RExec 'as.vector(dframe$residual)'
  0.9796694804 5.179764594 1.71311378 5.713232672 7.953394365 5.819997622 8.019973844 8.18012127 5.953037689 5.980501724

 もし APL で回帰を実行すれば(自家製の関数だが)

t1 <- 0.99 Regression ('depression' 'weight') (depression,[1.5]weight) 1 1 
Plot
Regression of depression on weight

Source        Sums of Squares     df   Mean Squares
===================================================
Model                  657.97      1         657.97
Residual               362.93      8          45.37
---------------------------------------------------
Total                 1020.90      9         113.43

Number of Observations                       10
F-statistic F(1,8)                           14.50
p-value, Prob > F                             0.0052
Variation accounted for (R-square)           64.45
               Adjusted (R-square)           60.01
 Root MSE (residual std deviation)            6.74

Variable         Estimate  StdError      t(8)  Prob>|t|      Mean
-----------------------------------------------------------------
depression                                                  14.10
-----------------------------------------------------------------
weight            2.66675   0.70024     3.808    0.0052      6.07
Intercept         2.087     4.754       0.439    0.6723

Correlation Coefficient:  80.28

 変数 t1 には様々な結果のリストが格納されている。例えば t1[2] は

   2  1.9  2.97966948   0.9796694804
   1  3.1  6.179764594  5.179764594
   5  3.3  6.71311378   1.71311378
   5  4.8 10.71323267   5.713232672
  20  5.3 12.04660564   7.953394365
  20  6.1 14.18000238   5.819997622
  23  6.4 14.98002616   8.019973844
  10  7.6 18.18012127   8.18012127
  30  9.8 24.04696231   5.953037689
  25 12.4 30.98050172   5.980501724

 R で生成されたフレームと同じである。(最初の2行が逆順)
 R プロットルーチンを使うことができる。例えば

RExec 'plot(roller.lm, which=1)'

 R グラフィックデバイスを用いて図形を生成し、JPEG として Rwhich1.jpeg で保存する。
 同様に Q-Q プロットは以下のように指定する。

RExec 'plot(roller.lm, which=2)' 

 通常はJPEGの精細を低くしておく。
 まだまだやり直したことがある特にテキストウィンドウを表示して要約のアウトプットを出力することである。

COM サーバを使う
(Perl におけるサンプルコード)

 このセクションは David Ovelleiro (mailto:dovelleiro@gmail.com) の貢献による。
 R パッケージで Perl アプリケーションへのインタフェースとして COM サーバを利用していたが、結果は極めてよいものである。http://sunsite.univie.ac.at/rcom/ には COM サーバを Visual Basic または Phyton で利用するサンプルがある。ユーザが DCOM 及び R で Perl を利用するサンプルを追加することもできるし、Perl の世界でのすばらしい方法を提供できるかもしれない。

use strict;
use Win32::OLE;

my $R =Win32::OLE->new('StatConnectorSrv.StatConnector');
my @cars;

$R->Init('R');
$R->EvaluateNoReturn ('plot(cars)');
$R->EvaluateNoReturn ('vec<-array(,dim=c(50,2))');
$R->EvaluateNoReturn ('for(i in 1:50){vec[i,1]<-cars[i,1]}');
$R->EvaluateNoReturn ('for(i in 1:50){vec[i,2]<-cars[i,2]}');
@cars=$R->GetSymbol ('vec');
my @cars_formatted=@{$cars[0]};

for (@cars_formatted){
print ${$_}[0]."\t".${$_}[1]."\n";
}

RServerManager: A Short Introduction

 R (D)COM サーバは Microsoft Excel のような標準的なアプリケーションや強力な計算エンジン及びグラフィック・テキスト出力のレンダラとして R を使うために COM クライアント(例:Visual Basic, Perl)として様々な言語で書かれたカスタムアプリケーション用の機構を提供する。
 R サーバパッケージの現在の実装では、クライアントアプリケーションにおいて使用されているそれぞれの R インタープリタを別々のアドレス空間にいれ、クライアントインスタンスにおいてさえインタープリタの複数のインスタンス用の異なるコードとデータセグメントを利用することを許している。
 他方、クライアントアプリケーションに R の機能を明示するために COM/DCOM を利用するとネットワーク上の同じマシン上でも異なるマシン上であっても、複数のクライアントアプリケーション間で R インタープリタのインスタンスを共有することができる。インタープリタインスタンスを共有することはデータ・コードセグメントも共有することも意味する。
 COM を使っての実装は、同時には1つのサーバの機能しか使わないようにインタープリタへのアクセスの同期に注意が必要である。
 これらの単一インタプリタの共有という COM/DCOM の特徴を使うにはクライアントアプリケーション及びこれらの協力においてインテリジェンスの水準を要求する。1つのクライアントはインタープリタインスタンスを生成し、全てのクライアントがアある種のデータ変換を行ってこのオブジェクトにアクセスを行う必要がある。
 このインタープリタの共有と管理を行うのが R Server Manager である。

Toolbox Logo
Updated : 2008/05/26