在Python中运行程序(R)以执行操作(执行脚本)的问题
我想从Python中执行一个R脚本,最好能显示和保存结果。使用rpy2让我有点头疼,所以我想直接调用R。我觉得我可能需要用到“os.system”或者“subprocess.call”,但是我在理解这些模块的使用说明时遇到了困难。
这是我的R脚本“MantelScript”,它使用一种特定的统计测试来比较两个距离矩阵(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)
这是我Python脚本中相关的部分,它会读取一些之前准备好的列表,并提取出矩阵,以便通过这个Mantel测试进行比较(它应该从identityA中提取第一个矩阵,并依次与identityB中的每个矩阵进行比较,然后再用identityB中的第二个矩阵重复这个过程,依此类推)。我想保存这些文件,然后调用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 个回答
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来实现这个功能。
2
坚持这个思路。
process = subprocess.Popen(['R', 'CMD', 'BATCH', 'C:/R/library/MantelScript.R'])
process.wait()
当 wait()
函数返回一个值时,说明 .R
文件的执行已经完成。
记得要把你的 .R
脚本写成可以让你的 Python 程序读取的文件。
with open( 'the_output_from_mantelscript', 'r' ) as result:
for line in result:
print( line )
不要浪费太多时间去连接一个复杂的流程。
先花时间搞定一个基本的“Python 启动 R”的过程。
之后你可以再进行扩展。
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']