※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

第3章 Ruby から R へのアクセス

3.1 Ruby から R オブジェクトを見つける。 R 関数と変数は、同じ方法で Ruby からアクセスできる。 Ruby とは違って、R の変数と関数は同じ名前を共有することが出来ないので、変数にアクセスしたいときに関数にアクセスすることはなくなります(ユーザのエラーを除いては)。 RPy と同様に、Ruby から R オブジェクトにアクセスする2つのメソッドがあります。しかし、RPy とは異なり、この2つのメソッドは exactly equivalent so some care should be taken. 最初に R オブジェクトを検索するメソッドは RSRuby インタプリタオブジェクトのメソッドを呼びます:

irb> r = RSRuby.instance
     => #<RSRuby:0xb7d30c04>
irb> r.seq
     => #<RObj:0xb7d2bc2c>
irb> r.as_data_frame
     => #<RObj:0xb7d29c88>
irb> r.print_
     => #<RObj:0xb7d27f8c>

今回の seq, as_data_frame と print_ は次の R 関数を返す。:

seq, as.data.frame と print。これらの関数は Ruby では RObj クラスのオブジェクトとして扱われ、

後のセクション 3.2 でもう少し学べます。 この名前の変換は Ruby メソッド名に沿った文字列を要求します。 この名前の変換ルールは Table 3.1 で示されているように RPy と同じです。

Ruby name  R name
Underscore (’_’) Dot (’.’)
Double underscore (’__’) Arrow (’<-’)
Final underscore (preceded by a letter) Is removed
       Table 3.1: 名前変換テーブル

以上のように同じ文法は R 変数を検索するのに使われます。次のように:

irb> r.foo
RException: Error in get(x, envir, mode, inherits) :
variable "foo" was not found
from /ruby/site_ruby/1.8/rsruby.rb:351:in ‘lcall’
from /ruby/site_ruby/1.8/rsruby.rb:351:in ‘__getitem__’
from /ruby/site_ruby/1.8/rsruby.rb:207:in ‘method_missing’
from (irb):5
irb> r.assign(’foo’,42)
     => 42
irb> r.foo
     => 42

最初の例では R オブジェクト foo が見つからないとき RSRuby では RException を要求されます。 R に存在する変数 foo に割り当てられた後 RSRuby により見つけかれます。 メモ、どんな引数もなしに R インタプリタからメソッドが呼ばれたとき、 Ruby オブジェクトと同じ名前の R オブジェクトが返されます。しかし、引数付きで呼ばれたとき、 要求されたオブジェクトは RObj (またはそのサブクラス)だと思われ、引数つきで呼ばれます。 Ruby から R への引数の変換は第4章で補足します。 セクション 3.2.1 でさまざまな呼び出しを説明します。 R オブジェクトにアクセスする2つの方法は、’[]’を使った Hash や Array スタイルのインタフェースです。 この方法は、上で見たメソッド呼び出し構文に比べると余分に見えるかもしれませんが、’[[’のような R 関数にアクセスする唯一の方法です。:

irb> r = RSRuby.instance
     => #<RSRuby:0xb7b32224>
irb> foo = r.as_data_frame(1)
     => {"1"=>1}
irb> r[’[[’].call(foo,1)
     => 1


メモ、文法「[]」は自動でオブジェクトを返しません。 例えば、 RObj は関数呼び出しにより「[]」を返します。 これについてはセクション 3.2.1 で検討します。(?)

3.2 RObj クラス R 関数と他のオブジェクトは RObj オブジェクトとして返された変換システムをハンドルしません。 RObj クラスには4つのメソッドが定義されています。:

as ruby: as_ruby は現在の変換システムにより RObj を Ruby へ強制的に変換する。もし変換できなければ、同じ RObj が返される。

call(args): RObj が与えられた引数を関数として扱うよう試します。本質的には引数は解釈され lcall に委譲されます。

lcall(args): lcall は低レベルな関数呼び出しです(C で書かれている)。 以下で説明します。

autoconvert: オブジェクトに変換モードを設定します。


3.2.1 R 関数の呼び方 R 関数を呼ぶルールは RPy とよく似ていますが、多少異なります。 明確なことは、Ruby では名前付き引数を直接サポートしませんが、R では、mix positional と名前つき引数が認められています。次善策として RObj の call が呼ばれ、最後の引数が Hash なら、Hash は関数のために名前つき引数のコレクションを扱います。 他の引数は現在の変換モードで適切な Ruby へ変換されます。 Note that もし R 関数が単純な R list を要求すると (通常は Ruby Hash として提供されます) 引数だけ, the lcall form given below must be used to prevent the Hash は名前付き引数のセットに変換されます。(?)

関数を呼ぶもっとも基本的は方法は lcall を使うことです。この関数の引数は、2種類のメンバ配列はフォームである必要があります。配列の最初の要素は、変数名であり、望むなら空文字列を残すことが出来ます。 lcall では要求された共有名と注文された引数両方で R 関数を許しています。

簡単な例をいくつか: 第一に、 名前つき引数の無い関数呼び出し(sum)。こんな感じです。:

irb> r.sum(1,2,3)
=> 6
irb> r.sum.call(1,2,3)
=> 6
irb> r.sum.lcall(’’,1],[’’,2],[’’,3)
=> 6

第二に、名前つき引数のある関数呼び出し(seq) :

irb> r.seq(:length => 10, :from => -5, :by => 1)
=> [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
irb> r.seq.call(:length => 10, :from => -5, :by => 1)
=> [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
irb> r.seq.lcall(’length’,10],[’from’,-5], [’by’,1)
=> [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]
Lastly, mixing named and non-named arguments:
irb> r.paste(’foo’,’bar’,{:sep => "baz"})
=> "foobazbar"
irb> r.paste.call(’foo’,’bar’,{:sep => "baz"})
=> "foobazbar"
irb> r.paste.lcall(’’,’foo’],[’’,’bar’], [’sep’,’baz’)
=> "foobazbar"