RからPythonスクリプトを実行する
私はRをメインで使い、サブでPythonを使います。
そんな私は、「基本はRで処理して、この処理だけPythonでやりたい!」と思うときがたまにあります。
そういったとき、RからPythonスクリプトを実行すれば解決します。
だけど、コマンドライン引数や返り値の書き方が覚えられない。
毎回調べるのも面倒なので本記事にメモしておきます。
とりあえずPythonスクリプトをRから実行する
まずは、コマンドライン引数や返り値は考えない。
とりあえずPythonスクリプトをRから実行する。
以下のPythonコードを"hello.py"で適当に保存。
print('Hello World')
次に"hello.py"をRから実行する。
Rで"hello.py"があるディレクトリに行って、以下のRコードを実行する。
system("python hello.py")
すると、
> system("python hello.py") Hello World
と表示されるはずです。簡単ですね!
Pythonスクリプトの返り値を受け取る
次は、RからPythonスクリプトを実行し、その返り値をRで受け取ります。
まずは以下のRコードを実行してみます。
ret=system("python hello.py") ret
すると、
> ret=system("python hello.py") Hello World > ret [1] 0
こうなって返り値として受け取れない。
返り値として受け取るには、Rのsystem関数の引数でintern=Tとするだけです。つまり、
ret=system("python hello.py",intern=T) ret
とするだけです。実行すると、
> ret=system("python hello.py",intern=T) > ret [1] "Hello World"
と表示されます。無事に返り値として受け取ることができました!
ちなみに複数の返り値を受け取りたい場合は、pythonで複数回printするだけです。
"hello.py"を以下に変更します。
print('Hello World1') print('Hello World2') print('Hello World3')
そして、Rから実行してみます。
> ret=system("python hello.py",intern=T) > ret [1] "Hello World1" "Hello World2" "Hello World3"
いい感じです!
Pythonスクリプトへコマンドライン引数を渡す
最後にPythonスクリプトにコマンドライン引数を渡します。
"hello.py"を以下に変更します。
import sys for i in range(len(sys.argv)): print(sys.argv[i])
そして、Rから
ret=system("python hello.py a b c",intern=T) ret
と実行してみます。
> ret=system("python hello.py a b c",intern=T) > ret [1] "hello.py" "a" "b" "c"
このように表示されたら成功です!
注意点としては、コマンドライン引数の1番目(Pythonでいう0番目)には自動でファイル名が入ることです。
そこだけ気をつけておきましょう。
まとめ
RからPythonスクリプトへコマンドライン引数を渡して実行し、その結果を返り値として受け取る方法について記載しました。
もちろんある程度大きなデータのやりとりをする場合は、csvなどのファイルを経由したほうが良いと思われます。
補足
pyenvでpythonを管理していて、特定のバージョンで実行したいときは、以下のRコードをはじめに実行すれば良いです。
Sys.setenv(PATH=paste("/Users/KYO/.pyenv/versions/anaconda3-4.1.1/bin", Sys.getenv("PATH"),sep=":"))
(anaconda3-4.1.1で実行したい場合)