我想从python执行R脚本,理想情况下显示和保存结果。使用rpy2有点挣扎,所以我想我只是直接打电话给R.我有一种感觉,我需要使用“os.system”或“subprocess.call”之类的东西,但我无法破译模块指南。
这是R脚本“MantelScript”,它使用特定的stat测试一次比较两个距离矩阵(distmatA1和distmatB1)。这在R中工作,虽然我还没有放入迭代位以便以成对的方式读取和比较一堆文件(我真的需要一些帮助,太btw! ):
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 ' '
答案 0 :(得分: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']
答案 1 :(得分: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”流程正常运作。
您可以稍后添加。
答案 2 :(得分: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来实现。
答案 3 :(得分: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
只是将两个文件名粘在一起;你可以用一个执行Mantel测试的函数替换它,比如(未经测试):
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)
}