4

私は、理想的には結果を表示して保存するために、PythonからRスクリプトを実行しようとしています。rpy2 を使用するのは少し苦労したので、R を直接呼び出すだけでよいと考えました。「os.system」や「subprocess.call」などを使用する必要があるような気がしますが、モジュール ガイドを解読するのに苦労しています。

これは R スクリプト "MantelScript" で、特定の統計テストを使用して一度に 2 つの距離行列 (distmatA1 と distmatB1) を比較します。これはRで機能しますが、一連のファイルをペアごとに読み込んで比較するための反復ビットをまだ入れていません(ところで、これについても支援が本当に必要です! ):

library(ade4)

M1<-read.table("C:\\pythonscripts\\distmatA1.csv", header = FALSE, sep = ",")
M2<-read.table("C:\\pythonscripts\\distmatB1.csv", header = FALSE, sep = ",")

mantel.rtest(dist(matrix(M1, 14, 14)), dist(matrix(M2, 14, 14)), nrepet = 999)

これは、以前に定式化されたいくつかのリストを読み取り、この Mantel Test を介してそれらを比較するために行列を引き出す、私の python スクリプトの関連部分です (identityA から最初の行列を取り出し、identityB のすべての行列と順次比較し、繰り返します)。 identityB からの 2 番目の行列など)。これらのファイルを保存してから、R プログラムを呼び出してそれらを比較したいと考えています。

# windownA and windownB are lists containing ascending sequences of integers
# identityA and identityB are lists where each field is a distance matrix.

z = 0
v = 0

import subprocess
import os

for i in windownA:                              

    M1 = identityA[i]                          

    z += 1
    filename = "C:/pythonscripts/distmatA"+str(z)+".csv"
    file = csv.writer(open(filename, 'w'))
    file.writerow(M1)


    for j in windownB:                          

        M2 = identityB[j]                     

        v += 1
        filename2 = "C:/pythonscripts/distmatB"+str(v)+".csv"
        file = csv.writer(open(filename2, 'w'))
        file.writerow(M2)

        ## result = os.system('R CMD BATCH C:/R/library/MantelScript.R') - maybe something like this??

        ## result = subprocess.call(['C:/R/library/MantelScript.txt'])  - or maybe this??

        print result
        print ' '
4

4 に答える 4

5

R スクリプトに副作用しかない場合は問題ありませんが、結果を Python でさらに処理したい場合は、rpy2 を使用した方がよいでしょう。

import rpy2.robjects
f = file("C:/R/library/MantelScript.R")
code = ''.join(f.readlines())
result = rpy2.robjects.r(code)
# assume that MantelScript creates a variable "X" in the R GlobalEnv workspace
X = rpy2.rojects.globalenv['X']
于 2010-07-27T09:34:42.997 に答える
2

これに固執します。

process = subprocess.Popen(['R', 'CMD', 'BATCH', 'C:/R/library/MantelScript.R'])
process.wait()

wait()関数が値を返すと、ファイル.Rは終了します。

Python プログラムが読み取ることができるファイルを生成するには、.R スクリプトを作成する必要があることに注意してください。

with open( 'the_output_from_mantelscript', 'r' ) as result:
    for line in result:
        print( line )

パイプラインを接続しようとして多くの時間を無駄にしないでください。

基本的な「Python spawns R」プロセスを機能させるために時間を費やしてください。

これは後で追加できます。

于 2010-07-26T21:51:13.313 に答える
2

一般的に Python から R サブプロセスを呼び出すことに関心がある場合。

#!/usr/bin/env python3

from io import StringIO
from subprocess import PIPE, Popen

def rnorm(n):
    rscript = Popen(["Rscript", "-"], stdin=PIPE, stdout=PIPE, stderr=PIPE)
    with StringIO() as s:
        s.write("x <- rnorm({})\n".format(n))
        s.write("cat(x, \"\\n\")\n")
        return rscript.communicate(s.getvalue().encode())

if __name__ == '__main__':
    output, errmsg = rnorm(5)
    print("stdout:")
    print(output.decode('utf-8').strip())
    print("stderr:")
    print(errmsg.decode('utf-8').strip())

Rscriptを介して行うことをお勧めします。

于 2010-07-28T17:06:30.690 に答える
0

あなたがやろうとしていることを考えると、純粋な R ソリューションの方がきれいかもしれません:

file.pairs <- combn(dir(pattern="*.csv"), 2) # get every pair of csv files in the current dir

ペアは 2xN 行列の列です。

file.pairs[,1]
[1] "distmatrix1.csv" "distmatrix2.csv"

apply を使用して、これらの列に対して関数を実行できます (オプション '2' を指定すると、'列に対する操作' を意味します)。

my.func <- function(v) paste(v[1], v[2], sep="::")
apply(file.pairs, 2, my.func)

この例my.funcでは、2 つのファイル名をくっつけただけです。これを Mantel Test を実行する関数に置き換えることができます (未テスト):

my.func <- function(v){
  M1<-read.table(v[1], header = FALSE, sep = ",")
  M2<-read.table(v[2], header = FALSE, sep = ",")
  mantel.rtest(dist(matrix(M1, 14, 14)), dist(matrix(M2, 14, 14)), nrepet = 999)
}
于 2010-07-28T07:20:19.703 に答える