10

R スクリプトを開き、別の python スクリプトによって定式化された入力を提供する必要があります。モジュールはこれsubprocessを行う良い方法のようです。

ただし、いくつかの不可解な結果に遭遇しましたp.stdin。これが私がこれまでに持っているものです:

from subprocess import Popen, PIPE, STDOUT

p = Popen(['r --no-save'],stdin=PIPE,stdout=PIPE,stderr=PIPE,shell=True)
p.stdin.write("source('myrscript.R')\n")
p.stdin.write('myfirstinput')

このコードを実行すると、 の最初のインスタンスがstdin.write()期待どおりに実行され (そして R スクリプトが開かれます)、2 行目では何も実行されず、サブプロセス (実際には R スクリプト) がエラーで終了し、サブプロセスが処理されたことを示します。入力が予期されていた場所で入力を受信しなかったため、終了しました。

注意 - 完璧な世界では、R を介して直接対話するだけですが、この特定のスクリプトには、実際には直接入力できない複雑な入力が必要です。また、rpy / rpy2 はオプションではありません。これは、このスクリプトのエンドユーザーが必ずしもそのモジュールまたはその依存関係にアクセスできるとは限らないためです。rscriptもオプションではありません (多くの理由がありますが、主にエンドユーザーの R 構成の可変性のためです)。

最後に、p.communicateこれはオプションではありません。明らかに、書き込み後にプロセスが閉じられ、開いたままにする必要があるためです。

前もって感謝します

4

1 に答える 1

5

あなたが必要とするのは、電話することです.communicate()

from subprocess import Popen, PIPE, STDOUT

p = Popen(
    ['r', '--nosave'],
    stdin=PIPE,
    stdout=PIPE,
    stderr=PIPE)
p.stdin.write("source('myrscript.R')\n")
p.stdin.write('myfirstinput\n')
p.stdin.write('q\n')

stdout, stderr = p.communicate()

print '---STDOUT---'
print stdout
print '---STDERR---'
print stderr
print '---'

討論

  • システムにRがインストールされていないため、偽のRスクリプトshell=Trueで動作しているようです。必要な場合と必要でない場合があります。
  • 示されているように、コマンド ラインを文字列のリストに分割することを好みますが、次のような単一の文字列でr --nosaveも機能します。両方を同時に行わないでください。
  • stdin.write()改行文字を書き込まないことを忘れない\nでください。自分で指定する必要があります。

アップデート

私の最初の試みは的外れでした。この 2 番目の試みが近づくことを願っています。JF Sebastian が提案したように、次を使用することをお勧めしますpexpect

import pexpect
import sys

if __name__ == '__main__':
    prompt = '> ' # Don't know what the R prompt looks like
    lines = ['one', 'two', 'three']

    r = pexpect.spawn('r --no-save', logfile=sys.stdout)
    for line in lines:
        r.expect(prompt)
        r.sendline(line)

    # If you want to interact with your script, use these two lines
    # Otherwise, comment them out
    r.logfile = None # Turn off logging to sys.stdout
    r.interact()

討論

  • をインストールする必要がある場合がありますpexpect。でやったpip install pexpect
  • システムとやり取りしたくない場合は、最後の 2 行をコメント アウトしますが、R スクリプトが終了するためのシグナルを必ず送信してください。
  • spawn()オブジェクトを返します。こちらspawnのドキュメントを参照してください。
于 2014-04-11T21:46:16.813 に答える