首页 > 解决方案 > 从 Python 调用并执行 r 脚本

问题描述

我正在尝试使用此 Python 脚本来调用 r 脚本并运行它。r 脚本是 dbc2csv.r,其代码位于 Python 块下方。我设法调用了 r 脚本并打开了 R studio,但是代码并没有像我希望的那样自动运行。我的感觉是subprocess.call线路有问题,但我不知道是什么。

import subprocess
import os

os.chdir("path")


def dbc2csv(raw_filename):
    dbc2csv_path = "Code\\R\\dbc2csv.R " + "Data\\CNES\\2005" + " " + "Data\\CNES\\2005"  + " " + raw_filename

    try:
        r_script_path = subprocess.getoutput('Code\\R\\dbc2csv.r')
        subprocess.call([r_script_path, "--vanilla", dbc2csv_path])
        return True
    except:
        print("dbc2csv - Error converting file: " + raw_filename)

        return False
 
dbc2csv("Data\\CNES\\STAC0508.dbc")

这是我试图调用和执行的 r 脚本。

#install.packages("read.dbc") You need this package
library("read.dbc")


dbc2dbf <- function(rawDir, convertedDir, file) {
  # reads dbc file
  x <- read.dbc(paste(rawDir, file, sep=""))
  # write it to csv
  write.csv(x, file=paste(convertedDir, file, ".csv", sep=""))
}

args = commandArgs(trailingOnly=TRUE)
try(dbc2dbf(args[1], args[2], args[3]), TRUE)

标签: pythonrsubprocess

解决方案


与可以在命令行自动运行的 Python .py 脚本类似,可以使用python.exeR 脚本运行Rscript.exe(R 安装目录的 bin 文件夹中的可执行文件)。这将在后台进程中运行 R 代码,而不需要像 RStudio 这样的 IDE。(请记住,就像任何编程语言一样,您可以在没有任何 IDE 的简单文本编辑器中编写 R 代码)。

下面使用subprocess.Popen哪个更有用捕获子进程的输出和错误以及更改子进程中的工作目录。另外,您在列表中传递 args 而不是空格分隔的字符串。请记住,子进程中的错误不会引发 Python 异常。

def dbc2csv(raw_filename):
   command = 'C:/Path/To/bin/Rscript.exe' 
   # command = 'Rscript'                    # OR WITH bin FOLDER IN PATH ENV VAR 
   arg = '--vanilla' 

   try: 
     p = subprocess.Popen([command, arg,
                          "Code/R/dbc2csv.R",
                          "Data/CNES/2005", 
                          "Data/CNES/2005",   
                          raw_filename],
                          cwd = os.getcwd(),
                          stdin = subprocess.PIPE, 
                          stdout = subprocess.PIPE, 
                          stderr = subprocess.PIPE) 

     output, error = p.communicate() 

     if p.returncode == 0: 
        print('R OUTPUT:\n {0}'.format(output.decode("utf-8"))) 
     else: 
        print('R ERROR:\n {0}'.format(error.decode("utf-8"))) 

     return True

   except Exception as e: 
     print("dbc2csv - Error converting file: " + raw_filename) 
     print(e)

     return False
   

推荐阅读