Python と R で連携する

# R と Python の連携を考える

最近 R による[基本的なデータプロッティング](http://qiita.com/ynakayama/items/c1bb0d92a712e58bf6fc)や[ファイル入出力の方法](http://qiita.com/ynakayama/items/42024cc320001d0eb9fb)について説明しました。

[データ分析の言語としては Python ですべてをやろうという傾向がある](http://www.excite.co.jp/News/it_g/20131129/Readwrite_534.html)ようですが、やはり過去の膨大な R による資産は魅力的でそう簡単に切り捨てられるものではありません。

よくあるケースとしては、部分的なデータ解析については R を流用したいが、全体的なプログラミングは Python で書きたいというシーンでしょう。また、プロッティングだけ R でおこないたいという場合もあるでしょう。こんなとき Python と R で連携できれば問題が一気に解決して便利です。

## Python から R を利用するライブラリ PypeR

かつては [RPy2](http://rpy.sourceforge.net/index.html) というライブラリが使われていたようですが、最近使われており主流なのは [PypeR](http://www.webarray.org/softwares/PypeR/) です。

### PypeR のインストール

インストールは簡単です。パッケージマネージャ pip でインストールします。

```bash
pip install pyper
```

## Python から R にデータを渡す

### R ソースコード

次のような R のコード (scatter.R) を考えてみます。

```r
png("image.png", width = 480, height = 480,
    pointsize = 12, bg = "white", res = NA)
plot(data$WRAIN, data$LPRICE2, pch=16,
     xlab="収穫前年の10月〜3月の雨量",
     ylab="ワインの価格")
dev.off()
```

これは data から 2 つの列を取り出しプロッティングして .png ファイルに書き出す単純な R ソースコードです。

### Python ソースコード

Python でこの R にデータを渡し、さらにオブジェクトを Python 側に取り出してみます。なお元データはワインの価格が保存された CSV ファイルで[こちら](https://github.com/ynakayama/sandbox/blob/master/python/R/wine.csv)から閲覧できます。

```py3
import pyper
import pandas as pd

# Python で CSV のデータを読み出す
wine = pd.read_csv("wine.csv")

# R のインスタンスを作る
r = pyper.R(use_pandas='True')

# Python のオブジェクトを R に渡す
r.assign("data", wine)

# R のソースコードを実行する
r("source(file='scatter.R')")
```

これで Python で読んだ wine.csv の内容が R に渡り、無事にプロッティングされます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/38501/4963b50c-b6fd-fc12-356a-dcf7814207e1.png)

## R のオブジェクトを Python から読む

### Python ソースコード

反対に R による処理結果を Python で取り出したくなることもあります。こういったときは r.get メソッドで R のオブジェクトを取り出すことができます。

```py3
# R のコードを実行する
r("res1 = cor.test(data$WRAIN, data$LPRICE2)")
r("data1 = subset(data, LPRICE2 < 0)")
r("res2 = cor.test(data1$WRAIN, data1$LPRICE2)")

# Python で R のオブジェクトを読む
res1 = pd.Series(r.get("res1"))
res2 = pd.Series(r.get("res2"))

print(res1)
#=>
#alternative                                  two.sided
#conf.int       [-0.258366126613384, 0.489798400688013]
#data.name                  data$WRAIN and data$LPRICE2
#estimate                                     0.1348919
#method            Pearson's product-moment correlation
#null.value                                           0
#p.value                                      0.5023297
#parameter                                           25
#statistic                                    0.6806807
#dtype: object

print(res2)
#=>
#alternative                                  two.sided
#conf.int       [-0.409535600260672, 0.364710477639889]
#data.name                data1$WRAIN and data1$LPRICE2
#estimate                                   -0.02636626
#method            Pearson's product-moment correlation
#null.value                                           0
#p.value                                      0.8982662
#parameter                                           24
#statistic                                   -0.1292127
#dtype: object
```

今回は pandas を利用しましたがこれは必須ではありません。しかし R と似た pandas のオブジェクトを直接やり取りできるのは非常に役に立ちます。

## まとめ

必要なときだけデータを R に渡して、さらに結果をオブジェクトとして Python に戻すことができます。一度データを外部ファイルに書き出して別々に実行するよりはるかに利便性が高いと言えるでしょう。 Python から R の資産を利用することができるため、ますます Python のグルー言語としての使い勝手が高まります。

## 参考

Python + PypeRでPythonからRをつかってみる
http://mia-0032.hatenablog.jp/entry/2013/08/30/000000

PythonからRを使いたい　-だがRPy2おめーはダメだ-
http://d.hatena.ne.jp/dichika/20130213/1360718736