PythonからRを使う(rpy2)

PSP株式会社の吉川です。
少し前にPythonからRを使いたくなる機会があったので、そのためのライブラリであるrpy2について書きます。
PythonからRを使うためのライブラリとしてはPypeRというものもあるのですが、こちらはしばらく更新されておらず、また、公式ドキュメントもリンク切れのようでした。

使い方

robjectsをインポートし、ここにRのコードを渡していきます。

from rpy2 import robjects

r = robjects.r

r("a <- 1")
r("b <- 2")
print(r("a + b"))

# 結果
# [1] 3

結果はベクトルで返ってくるので以下のようにして取り出します。

print(1 + r("b")[0])

# 結果
# 3.0

反対にPython側の値をRに渡す際にはassignを使います。

c = 5
r.assign("c", c)
print(r("a + b + c"))

# 結果
# [1] 8

PandasのデータフレームをRのデータフレームに変換して渡す、といったこともできます。

import pandas
from rpy2.robjects import pandas2ri

csv_x = pandas.read_csv("X.csv")
with (robjects.default_converter + pandas2ri.converter).context():
    r_csv_x = robjects.conversion.get_conversion().py2rpy(csv_x)
r.assign("X", r_csv_x)
r("Y <- X[seq(3,5),]")

反対にRのデータフレームをPandasのデータフレームに変換して受け取ることもできます。

r("name <- c('a','b','c')")
r("val1 <- c('1','2','3')")
r("val2 <- c('6','5','4')")
r("df <- data.frame(name,val1,val2)")

with (robjects.default_converter + pandas2ri.converter).context():
    r_df = r("df")
    pd_df = robjects.conversion.get_conversion().rpy2py(r_df)
pd_df.sort_values(["val2"])

Rの関数をPython側に持ってきて使うこともできます。
引数はRにあわせた形にする必要があります。

rmean = r("mean")
rvector = robjects.IntVector([1,10])
print(rmean(rvector))

# 結果
# [1] 5.5

ファイルからスクリプトを読み込むsource関数を持ってくることでRファイルをPython側から実行できます。

rsource = r("source")
rsource("rscript.R")


まとめ

rpy2の使い方について書いてきました。
「データ分析などでPythonとRを行き来する必要がある」といったわけではなく、単にPythonからRを実行したいだけならRのスクリプト内にcsvの読み込みから出力まですべてまとめてしまい、Python側では以下のようにしておけばよさそうです。

robjects.r.assign("csvpath", csvpath)
robjects.r("source")("rscript.R")
print(robjects.r("result")[0])