2

I would like to run an R script from python, and capture the output into a .Rout type file. The R script takes command line arguments. I am struggling... Minimal working example follows.

R script:

job_reference <- commandArgs(trailingOnly = TRUE)
arg1 <- job_reference[1]
arg2 <- job_reference[2]
arg3 <- job_reference[3]
arg4 <- job_reference[4]
print("***")
print(paste(arg1, arg2, arg3, arg4))
print("***")

python script:

import subprocess
arg1 = 'a'
arg2 = 'b'
arg3 = 'c'
arg4 = 'd'
subprocess.call(["/usr/bin/Rscript",  "--no-save", "--no-restore", "--verbose", "print_letters.R",  arg1, arg2,  arg3, arg4, ">", "outputFile.Rout", "2>&1"])

The last line in the python script is via this stackoverflow link.

If I run the python script, the "outputFile.Rout" is not produced. However the python output includes:

running
'/usr/lib/R/bin/R --slave --no-restore --no-save --no-restore --file=print_letters.R --args a b c d > outputFile.Rout'

and when I run that from the command line without involving python the output file is produced. Note that I have tried specifying full paths to output files, etc.

Can anyone explain i) what is happening here; ii) how I can run an R script from python with the R script accepting command line arguments and producing an Rout type file?

Thanks in advance.

1 Answer 1

4

i) what is happening here

The Rscript call you grabbed makes use of a shell feature called i/o redirection. In particular, the end of that command, > outputFile.Rout 2>&1 is a special shell feature that means roughly redirect all the output from the command into the file "outputFile.Rout", oh and also redirect standard error to standard out so it ends up in that file as well.

From the subprocess docs,

shell=False disables all shell based features

in other words, the default for subprocess.call() is to run the command without using the shell, so you don't get access to the shell based features. Instead the '>' and 'outputFile.Rout' for instance are passed directly as args to R, just like a.

ii) run R script with output redirect

While there a couple ways to go about this, such as using os.system() or passing shell=True to subprocess.call() and passing the command as a string, the recommended way is just to use the machinery in subprocess to do the equivalent i/o redirection:

with open('outputFile.Rout','w') as fileobj:
    subprocess.call(["/usr/bin/Rscript",  "--no-save", "--no-restore",
                     "--verbose", "print_letters.R", 
                     arg1, arg2,  arg3, arg4], 
                     stdout=fileobj, stderr=subprocess.STDOUT)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.