Rpy2を使うと、PythonからRを利用できます。
公式ページより引用。
rpy2 is an interface to R running embedded in a Python process.
The project is mature, stable, documented, and widely used (older documentation).
Rpy2に関連した前回までの記事は以下の通り。
- Pythonからよく使うRの統計関数を簡単に呼び出せるようにしてみた (多重比較・Rpy2)
- rpy2_wrapperを使ってPythonコードで統計検定(TukeyHSD・Dunnett・Steel-Dwassなど)
Rpy2の環境構築手順については、1つ目の記事を参照のこと。
今回は、Rpy2の使い方について、今のところ把握している範囲のみご紹介します。
#Rpy2の使い方
公式ページを参考に。
rpy2.robjects.rを使ってRの関数を実行
まず、rpy2.robjects
をインポートします。
import rpy2.robjects as ro
ro.r
の引数に、Rで実行したい内容を文字列で渡します。
result = ro.r("2")
print(result)
# [1] 2
ro.r
に数値を渡した場合、ベクトルになる点に注意。
print(type(result))
# <class 'rpy2.robjects.vectors.FloatVector'>
数値のみを取り出したい場合は以下のように要素を指定します。
print(result[0])
# 2.0
数式でも同様にro.r
で実行できます。
result = ro.r("2 + 2")
print(result[0])
# 4.0
ro.r
の中で行ったRの変数代入は、その後に実行するro.r
の中でも引き継がれます。以下の例の"a"のような感じ。
ro.r("a <- 2")
print(ro.r("a * 2")[0])
# 4.0
数列は以下のように入力します。
r_array = ro.r("c(1,50,4,7,10,3)")
print(r_array)
# [1] 1 50 4 7 10 3
このように、ro.r
がRpy2の基本機能になります。
rpy2.robjectsでRの関数を使う(mean()
を例に)
Rの関数を使う場合、主に2つの方法があります。
1つ目は、前述のro.r
で代入した変数に対して、ro.r
内で処理する方法です。
ro.r("a <- c(1,50,4,7,10,3)")
ro.r("mean(a)")[0]
# 12.5
2つ目は、関数をオブジェクトとしてpythonの変数に代入し、その変数を関数として扱う方法です。
result = ro.r("c(1,50,4,7,10,3)")
mean = ro.r["mean"]
mean(result)[0]
# 12.5
1つ目の方はRそのままなので楽です。2つ目の方はPythonっぽい書き方ですね。
Pythonで定義した変数をro.r
で使えるようにする
ro.r.assign()
を使うとPythonで定義した変数をro.r
内の変数として引き渡すことができます。
ro.r.assign()
の1つ目の引数に引き渡し先のro.r
内の変数、2つ目の引数にPythonで定義した変数を渡します。
a = 1
ro.r.assign("a", a)
print(ro.r("a")[0])
# 1
print(ro.r("a * 2")[0])
# 2.0
この機能は地味に便利です。
##Rのパッケージの呼び出し方
Rのパッケージを呼び出すlibrary(r_package)
に相当するRpy2の機能はrpy2.robjects.packages.importr
です。
from rpy2.robjects.packages import importr
multcomp = importr("multcomp")
呼び出したパッケージの関数は、以下の3つのいずれでも利用可能なようです。
- ro.r("関数名")
- ro.r["関数名"]
- multcomp.関数名
パッケージごとの使い方の違いなどはまだ把握できていません。
注:パッケージのインストールはあらかじめ、コマンドラインのRの方で行っておくのがラクです。(参考ページ)
##NumPy, Pandas <-> R
個人的な意見ですが、Rpy2のもっとも素晴らしいところは、NumPyやPandas形式のデータが簡単に利用できるところだと思っています。
Rに慣れていないと、Rのアレイやデータフレームの取り扱いは地味に苦痛です。Rpy2のこの機能を使えば、NumPyやPandasでデータ整理を行った後に、Rにデータを渡してそのまま解析することが可能です。これは、Pythonユーザーの私にとってはめちゃ快適です。
やり方は以下の通り。
###NumPy <-> R
NumpyからRへの変換にはnumpy2ri.py2ri()
を使います。
import numpy as np
from rpy2.robjects import numpy2ri
py_array = np.array([[1,4,3,6,3],[1,5,3,4,10]])
ro.r.assign("r_array",numpy2ri.py2ri(py_array))
print(ro.r("r_array"))
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 4 3 6 3
# [2,] 1 5 3 4 10
numpy2ri.activate()
を実行するとRのアレイが自動的にNumpyのアレイに変換されるようになります。
numpy2ri.activate() #numpy<->Rをアクティブに
r_array = ro.r("c(1,50,4,7,10,3)")
print(r_array)
# [ 1. 50. 4. 7. 10. 3.]
print(type(r_array))
# <class 'numpy.ndarray'>
###Pandas <-> R
Pandasの場合は、pandas2ri.activate()
やpandas2ri.py2ri()
を使います。NumPyと似ているので覚えやすい。
import pandas as pd
from rpy2.robjects import pandas2ri
pandas2ri.activate()
py_df = pd.DataFrame(py_array)
r_df = ro.r.assign("r_df",pandas2ri.py2ri(py_df))
r_df
R/rpy2 DataFrame (2 x 5)