4

I am trying to use this Python script to call an r script and run it. The r script is dbc2csv.r, whose code is below the Python block. I managed to call the r script and R studio opens but then the code does not run automatically as I would like it to happen. My feeling is that there is something wrong in the subprocess.call line but I can't figure out what.

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")

This is the r script I am trying to call and execute.

#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)
PhDing
  • 163
  • 1
  • 9

2 Answers2

5

Similar to Python .py scripts that can be automatically run at command line with python.exe, R scripts can be run with Rscript.exe (an executable in bin folder of R installation directory). This will run R code in background process without need of an IDE like RStudio. (Remember like any programming language you can write R code in simple text editor without any IDE).

Below uses subprocess.Popen which is more useful to capture output and error of child process and change working directory in child process. Plus, you pass args in a list instead of space separated string. Remember an error in child process will not raise a Python exception.

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
   
Parfait
  • 104,375
  • 17
  • 94
  • 125
2

You should not call the R script through Rstudio, but with Rscript. This is a command line program that comes with R and is provided for particular this purpose.

If you write the result to a CSV file, I would not hard code it into your R script, but pass the filename to the script as a command line parameter (can be obtained in the R script with commandArgs). Then you can store the file in a temporary directory, as e.g. created with the python module tempfile.

cdalitz
  • 1,019
  • 1
  • 6
  • 7
  • Not really helpful - if it runs in RStudio, why would it not run in RScript? Also OP is trying to run from Python and not from console! – Sebastian Hätälä Jul 03 '20 at 14:13
  • 1
    @shtala: OP runs it through *subprocess*, which allows for stdin/stdout redirect. As the filenames apparently are on a Windows OS, you need a command line program for using anonymous pipes, which simply won't work with Rstudio. Moreover, the quetsion is about running an R scirpt NOT interactively but from Python, which is exactly the use case for Rscript. – cdalitz Jul 03 '20 at 14:16