system 関数を使ってR のコンソールからターミナルへコマンドを送って実行する

R を使っていろいろやっているときに、R だけで完結すればいいが、R で実行できない関数や実装されていない仕様みたいなものがあって、計算がはかどらないときがある。
そういうときは別のプログラムを使ってその部分の計算をして、その結果をファイルに書き出しておいてそのあとR で読み込む、ということができなくもないが、そのコード部分を別に書いてシェルスクリプトにするのは、まあいいけどR に書いて実行したい。
そういうときにsystem 関数が使えるらしい。
 
実行環境はubuntu 14.04 でpython3 を使ってみる。
 
ターミナルで実行するコマンドを文字列として書いておいて、system() するだけ。
ここで、R ではできないけれどもPython には関数があって、Python を実行するという設定でやってみる。
R でPython の結果を利用するのはrPython パッケージがあるが、rPython パッケージを導入するのにミスってうまく行かないようなときにやってもいいと思う。
 
まずはpython 用のコードを書く。数字を入力として、それらの自乗を返すとする。
これをバッチモードで実行する。

# code.py
# -*- encoding: utf-8 -*-
import os, sys, re
import numpy as np

def main():
  input_args = sys.argv[1:]
  arg = list(map(float, input_args))
  tmp = np.array(arg)
  output = tmp ** 2
  #print(output)
  print(" ".join(list(map(str, output))))

if __name__ == '__main__':
  main()

ここで、numpy の仕様的に、ただprint すると

[  1.    16.     9.     5.76]

となるので、適当に文字列にして体裁を整えて

1.0 16.0 9.0 5.76

とする。
ターミナルでの実行は、

python3 code.py arg1 arg2 arg3

となる。
 
さてこれをR で実行して、ターミナルでのpython バッチモードとして実行したい。R でのコマンドは

command <- sprintf("python3 code.py %d %d %d", 2, 5, 7)
system(command)

となる。これで、R のコンソールにターミナルでの実行結果が出力される。

4.0 25.0 49.0

 
ではこれをR のオブジェクトに記録して、その後の計算に使いたいとする。rPython ならばassign などで取ってこれる(たはず)だが、R のコンソールへの出力を入手したい。
この場合はintern=TRUE にする

hoge <- system(command, intern=TRUE)
[1] "4.0 25.0 49.0"

これで標準出力結果を取得できるし、R コンソールへの出力様式もいつものR っぽいやつになる。