LoginSignup
17
17

More than 5 years have passed since last update.

Rpy2の使い方の備忘録

Posted at

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に関連した前回までの記事は以下の通り。

Rpy2の環境構築手順については、1つ目の記事を参照のこと。

今回は、Rpy2の使い方について、今のところ把握している範囲のみご紹介します。

Rpy2の使い方

公式ページを参考に。

Introduction to 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)


Table.png

小ネタ

ro.rの引数として渡すRのコードはダブルクオーテーション""で囲っています。もし、Rの関数内でもクオーテーションを使う必要がある場合には、シングルクオーテーション''とダブルクオーテーション""で使い分ける必要があります。

以上です。

17
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
17