Symfoware

Symfowareについての考察blog

Pythonからrpy2でRのソースファイルを呼び出すときに値を渡す方法

Pythonでデータベースに接続し、データを加工してcsvファイルを出力。
グラフの生成はR先生おねがいします。ということをやりたい。



準備



Debianで動作確認しています。
Rをインストールする手順をすっかり忘れていました。

Debian 7にRの実行環境(3.1.1)をapt-getでインストールする

ざっくりメモしてきます。

sources.listを編集。


# vi /etc/apt/sources.list




末尾に一行追加


deb http://cran.ism.ac.jp/bin/linux/debian wheezy-cran3/




認証キーを追加し、更新。


# apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 06F90DE5381BA480
# apt-get update




Rのインストール


# apt-get install r-base






呼び出されるRプログラム



テキストデータを読み取り、折れ線グラフを描画するサンプルです。
line.rというファイル名で以下の内容を保存しました。


  1. png("image.png", width = 500, height = 300, pointsize = 12, bg = "white")
  2. # データの読み込み
  3. csv <- read.csv("data.csv", header=T)
  4. # plot関数でデータを配置
  5. plot(csv$x, csv$y, type="o", main="タイトル")
  6. graphics.off()




読み込むdata.csvはこんな感じ。


x,y
1,1
2,2
3,3
4,4
5,5
6,6
7,7
8,8
9,9
10,10




プログラムを実行してみます。


# Rscript line.r




こんなグラフが得られました。

556_01.png


line.rをPythonから呼び出してみます。





rpy2



PythonからRを呼び出すモジュールがいくつかあるようです。
Python で R

今回は、rpy2を使用することにしました。
http://rpy.sourceforge.net/

Debianにapt-getでインストールします。


# apt-get install python-rpy2




Introduction to rpy2

ドキュメントを見てみると、RのソースをPythonで定義するような使い方が多いですが、
今回既にRのプログラムは作成済です。

Rソースを直接実行するには、このようにします。


  1. # -*- coding:utf-8 -*-
  2. import rpy2.robjects as robjects
  3. # line.rを直接実行
  4. robjects.r("source(file='line.r')")



これでグラフが描画された画像ファイルが出力されるはずです。







Pythonの変数を渡す



今回の例で言うと、読み込むファイル名やグラフタイトルが固定値です。
ここをPythonから指定し、動的に変更したいと思うのが人情です。

やり方がわからなくてずいぶん悩んだのですが、
Introduction to rpy2

ここのドキュメントをよく読んでみると、「globalenv」を使えば良さそう。

Python側では、


robjects.globalenv["キー名"] = 変数



の形式で渡したい値を設定します。
また、同じオブジェクトから、Rで設定した値も取得できます。


  1. # -*- coding:utf-8 -*-
  2. import codecs
  3. import rpy2.robjects as robjects
  4. with codecs.open('data_2015.csv', 'w', 'utf-8') as f:
  5.     
  6.     # 本当はデータベースから取得した値を出力
  7.     # ヘッダー
  8.     f.write(u'x,y\n')
  9.     
  10.     # データ部
  11.     f.write(u'%d,%d\n' % (1, 1))
  12.     f.write(u'%d,%d\n' % (2, 3))
  13.     f.write(u'%d,%d\n' % (3, 5))
  14.     f.write(u'%d,%d\n' % (4, 7))
  15.     f.write(u'%d,%d\n' % (5, 9))
  16.     f.write(u'%d,%d\n' % (6, 11))
  17.     f.write(u'%d,%d\n' % (7, 13))
  18.     f.write(u'%d,%d\n' % (8, 15))
  19.     f.write(u'%d,%d\n' % (9, 17))
  20.     f.write(u'%d,%d\n' % (10, 19))
  21.     
  22. # Rに渡したい値を設定
  23. robjects.globalenv["file_name"] = 'data_2015.csv'
  24. robjects.globalenv["graph_title"] = '2015'
  25. # line.rを直接実行
  26. robjects.r("source(file='line.r')")
  27. # 実行後にRで設定された値を読み込み
  28. print robjects.globalenv["result"]
  29. # 結果はrpy2.robjects.vectors.StrVectorで取得できる
  30. # Pythonの文字列で取得したい場合は、r_repr()すればOK
  31. print robjects.globalenv["result"].r_repr()





R側のプログラムはこうなりました。


  1. png("image.png", width = 500, height = 300, pointsize = 12, bg = "white")
  2. # データの読み込み
  3. # 「file_name」はPythonから渡された値
  4. csv <- read.csv(file_name, header=T)
  5. # plot関数でデータを配置
  6. # graph_titleはPythonから渡された値
  7. plot(csv$x, csv$y, type="o", main=paste(graph_title, "年の実績", sep=""))
  8. graphics.off()
  9. # Python側に通知したい値
  10. result <- "ok"




Rで文字列を結合するのはpasteを使わなければならず地味に面倒なので、
Python側で用意したほうが良さそうです。

17. 文字列を操作する


pythonのコードはsample.pyという名前で保存しています。
実行して結果を見てみます。


# python sample.py
[1] "ok"

"ok"




ちゃんとRで設定した"ok"という文字列が受け取れていますね。
出力されたグラフを見てみます。

556_02.png

狙い通りの結果が得られました。



R言語 掲載記事のまとめ



【参考URL】

Python で R

17. 文字列を操作する

Introduction to rpy2




関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2015/02/21(土) 19:02:37|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Cordova(コルドバ)チュートリアル1 Cordovaプロジェクトの作成 | ホーム | Jenkins + GitBucket + Fabricを使用し、ボタンひとつでwebサーバーにデプロイ>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1637-ac25d70e
この記事にトラックバックする(FC2ブログユーザー)