【问题标题】:Running R script from python从 python 运行 R 脚本
【发布时间】:2013-11-22 13:07:49
【问题描述】:

我搜索了这个问题并找到了一些答案,但它们似乎都不起作用。这是我在 python 中用来运行我的 R 脚本的脚本。

import subprocess
retcode = subprocess.call("/usr/bin/Rscript --vanilla -e 'source(\"/pathto/MyrScript.r\")'", shell=True)

我得到这个错误:

Error in read.table(file = file, header = header, sep = sep, quote = quote,  : 
  no lines available in input
Calls: source ... withVisible -> eval -> eval -> read.csv -> read.table
Execution halted

这是我的 R 脚本的内容(很简单!)

data = read.csv('features.csv')
data1 = read.csv("BagofWords.csv")
merged = merge(data,data1)
write.table(merged, "merged.csv",quote=FALSE,sep=",",row.names=FALSE)
for (i in 1:length(merged$fileName))
{
        fileConn<-file(paste("output/",toString(merged$fileName[i]),".txt",sep=""))
        writeLines((toString(merged$BagofWord[i])),fileConn)
        close(fileConn)
}

当我在 r 命令行中使用 source('MyrScript.r') 时,r 脚本工作正常。此外,当我尝试使用我在命令行中传递给subprocess.call 函数(即/usr/bin/Rscript --vanilla -e 'source("/pathto/MyrScript.r")')的确切命令时,它可以找到,我真的不明白问题出在哪里。

【问题讨论】:

  • 尝试为您的 csv 文件指定完整的文件路径,也许?
  • 试试strace,看看exec调用的区别是什么。

标签: python r


【解决方案1】:

我不建议使用系统调用,因为 python 和 R 之间存在很多差异,尤其是在传递数据时。

有许多标准库可以从 Python 调用 R 以供选择,请参阅answer

【讨论】:

  • 您好,我只需要运行一个简单的脚本,所以我不想拘泥于设置 rpy2 或其他库。
  • @Ehsan 设置起来相当简单,您将避免重新发明轮子。你是在 windows、mac 还是 linux 上?
  • @Ehsan 和另一个建议,如果您所做的只是用 R 加载 csv 文件,为什么不直接将 R 代码重写为 python?
  • 我用的是linux,它不只是加载一个csv文件,而是我会在rpy2上搜一搜,看看怎么样:)
  • 是的,如果你在 ubuntu 上它就像 sudo apt-get install python-rpy2 一样简单
【解决方案2】:

我认为 RPy2 值得研究,这是 R-bloggers.com 上的一个很酷的演示文稿,可以帮助您入门:

http://www.r-bloggers.com/accessing-r-from-python-using-rpy2/

本质上,它允许您访问带有 R 对象的 R 库,这些对象提供高级和低级接口。

以下是最新版本的文档:https://rpy2.github.io/doc/latest/html/

我喜欢将 Python 用户指向 Anaconda,如果您使用包管理器 conda 来安装 rpy2,它也将确保您安装 R。

$ conda install rpy2

这是基于文档介绍的小插曲:

>>> from rpy2 import robjects
>>> pi = robjects.r['pi']
>>> pi
R object with classes: ('numeric',) mapped to:
<FloatVector - Python:0x7fde1c00a088 / R:0x562b8fbbe118>
[3.141593]

>>> from rpy2.robjects.packages import importr
>>> base = importr('base')
>>> utils = importr('utils')

>>> import rpy2.robjects.packages as rpackages
>>> utils = rpackages.importr('utils')
>>> packnames = ('ggplot2', 'hexbin')
>>> from rpy2.robjects.vectors import StrVector
>>> names_to_install = [x for x in packnames if not rpackages.isinstalled(x)]
>>> if len(names_to_install) > 0:
...     utils.install_packages(StrVector(names_to_install))

并运行 R sn-p:

>>> robjects.r('''
...         # create a function `f`
...         f <- function(r, verbose=FALSE) {
...             if (verbose) {
...                 cat("I am calling f().\n")
...             }
...             2 * pi * r
...         }
...         # call the function `f` with argument value 3
...         f(3)
...         ''')
R object with classes: ('numeric',) mapped to:
<FloatVector - Python:0x7fde1be0d8c8 / R:0x562b91196b18>
[18.849556]

还有一个独立的小图形演示:

from rpy2.robjects.packages import importr
graphics = importr('graphics')
grdevices = importr('grDevices')
base = importr('base')
stats = importr('stats')

import array

x = array.array('i', range(10))
y = stats.rnorm(10)

grdevices.X11()

graphics.par(mfrow = array.array('i', [2,2]))
graphics.plot(x, y, ylab = "foo/bar", col = "red")

kwargs = {'ylab':"foo/bar", 'type':"b", 'col':"blue", 'log':"x"}
graphics.plot(x, y, **kwargs)


m = base.matrix(stats.rnorm(100), ncol=5)
pca = stats.princomp(m)
graphics.plot(pca, main="Eigen values")
stats.biplot(pca, main="biplot")

【讨论】:

    【解决方案3】:

    我不会太相信Rscript 调用中的来源,因为您可能不完全了解您在哪里运行不同的嵌套 R 会话。该过程可能会因为一些简单的事情而失败,例如您的工作目录不是您想的那样。

    Rscript 让您可以直接运行脚本(如果您使用的是 Linux,请参阅man Rscript)。

    那你可以直接做:

    subprocess.call ("/usr/bin/Rscript --vanilla /pathto/MyrScript.r", shell=True)
    

    或更好地将Rscript 命令及其参数解析为列表

    subprocess.call (["/usr/bin/Rscript", "--vanilla", "/pathto/MyrScript.r"])
    

    另外,为了让事情变得更简单,您可以创建一个 R 可执行文件。为此,您只需在脚本的第一行添加:

    #! /usr/bin/Rscript
    

    并赋予它执行权。有关详细信息,请参阅here

    然后您就可以像调用任何其他 shell 命令或脚本一样执行您的 python 调用:

    subprocess.call ("/pathto/MyrScript.r")
    

    【讨论】:

    • subprocess.call() 在我的情况下不起作用,但 subprocess.Popen() 对我有用。这是示例: process = subprocess.Popen(["R --vanilla --args %s %d %.2f
    • 所有这些对我来说都是一样的:subprocess.call (['Rscript', '--vanilla', 'MyrScript.r']) subprocess.Popen(['Rscript', '--vanilla', 'MyrScript.r']) subprocess.call ('Rscript --vanilla MyrScript.r', shell=True) subprocess.Popen('Rscript --vanilla MyrScript.r', shell=True) 如果你不将参数分解成一个列表,那么当你需要使用 shell+True 我不确定使用 @ 将参数解析为 Rscript 987654332@
    【解决方案4】:

    如果您只想运行一个脚本,那么您可以使用sys 库中的system("shell command") import sys。如果你有一个有用的输出,你可以在你的 shell 命令结束时通过" &gt; outputfilename" 打印结果。

    例如:

    import sys
    
    system("ls -al > output.txt")
    

    【讨论】:

    • 我不知道这存在。它是否较旧/过时?它可以将输出保存为字符串吗?
    • 我不知道它是否已经过时,但是你可以得到输出。使用此命令,您可以调用 shell 命令,因此如果使用 > 更改输出目标,则可以使用输出文件返回结果。
    【解决方案5】:

    尝试在 R 脚本的开头添加一行:

    setwd("path-to-working-directory")
    

    除了,将路径替换为包含文件features.csvBagofWords.csv 的文件夹的路径。

    我认为您遇到的问题是因为当您从 R 运行此脚本时,您的工作目录已经是正确的路径,但是当您从 python 运行脚本时,它默认为其他地方的工作目录(可能是顶部用户目录)。

    通过在 R 脚本的开头添加额外的行,您可以明确设置工作目录,并且读取这些文件的代码将起作用。或者,您可以将read.csv() 中的文件名替换为这些文件的完整文件路径。

    @dmontaner 在他的回答中提出了这种可能性:

    这个过程可能会因为一些简单的事情而失败,比如你的工作目录不是你想象的那样。

    【讨论】:

      【解决方案6】:

      以下代码应该可以运行:

      import rpy2.robjects as robjects
      robjects.r.source("/pathto/MyrScript.r", encoding="utf-8")
      

      【讨论】:

        猜你喜欢
        • 2013-05-03
        • 2016-12-15
        • 1970-01-01
        • 2015-11-24
        • 2018-09-30
        • 2018-09-22
        • 2014-03-03
        • 2013-10-24
        • 2011-02-04
        相关资源
        最近更新 更多