1

I want to run a RScript that plots some data which is fetched by a QGIS Plugin. However it returns a non zero-exist status and breaks (when running with subprocess.check_call) or just skips the command when calling subprocess.call / subprocess.Popen.

Things I've done so far:

check_call:

script_filename = "/myRscript/that/plots/some/stuff.R"
csvpath = "/path/of/csvdata.csv"
output_dir = "/output/directory"
p1 = subprocess.check_call(['/Library/Frameworks/R.framework/Versions/3.5/Resources/Rscript', script_filename, "-f", csvpath, "-o", output_dir], shell=False)

returns following Error:

>>> subprocess.CalledProcessError: Command '['/Library/Frameworks/R.framework/Versions/3.5/Resources/Rscript', '(...)createProfile.R', '-f', '(...)profile_data.csv', '-o', '(...)4 MASTERARBEIT']' returned non-zero exit status 1.

Popen:

p1 = subprocess.Popen(['/Library/Frameworks/R.framework/Versions/3.5/Resources/Rscript', script_filename, "-f", csvpath, "-o", output_dir], shell=False)
p1.wait()
>>> 1

However, the calls work fine when I try to call them from a standard python session outside of QGIS. What is even more irritating is that a command like subprocess.check_call(['open', output_dir], shell=False)works inside QGIS.

BTW, I'm on Mac OS X High Sierra and QGIS 3.2.0 Bonn / Python 3.6.

  • It has run the Rscript executable but that script has returned with an error status code. Is there anything in the output directory? – Spacedman Nov 27 '18 at 14:53
  • No unfortunately not. It seems that the QGIS Python version somehow behaves differently to the normal system version... – Valentin Nov 27 '18 at 15:10
  • Can you run a trivial R script, called with no options? eg subprocess.check_call(["Rscript","msg.R"]) where msg.R contains message("hello")? With everything in the right directory of course... – Spacedman Nov 27 '18 at 15:18
  • This returns exit status 2...however I'm not sure if I'm referencing the file correctly. I just copied it to my plugins folder where all the plugin's python scripts located. – Valentin Nov 27 '18 at 15:26
  • 1
    I additionally changed my R Script to ignore the command line arguments and switched to fixed paths on my system, which is working so far. Still strange why it doesn't accept the arguments when they come from qgis python but accepts them if they come from the system python version... – Valentin Nov 27 '18 at 15:42
0

Thanks to the suggestions and help of @Spacedman I was able to find a way to solve the problem. I had to modify the processing of my R command line arguments inside the R script and changed it to following:

R Script msg.R:

library("optparse")

option_list = list(
  make_option(c("-f", "--file"), type="character", default="/Users/Valentin/Desktop", 
              help="dataset file name", metavar="character")
); 

opt_parser = OptionParser(option_list=option_list);
opt = parse_args(opt_parser);
if (is.null(opt$file)){
  print_help(opt_parser)
  stop("At least one argument must be supplied (input file)", call=FALSE)
}

print(opt$file)
fileConn<-file(opt$file)
writeLines(c("Hello","World"), fileConn)
close(fileConn)

The QGIS / Python side looks like this:

main_plugin_file.py:

# get filename of python file in the plugin, get the directory of it and append the msgR file 
pyfile = os.path.realpath(__file__)
plugin_folder = os.path.normpath(pyfile.replace(os.path.basename(pyfile),""))
msgR_path = os.path.join(plugin_folder,"msg.R") # msg.R is in the same folder as the plugin
outpath = os.path.join(output_dir, "thisworksnow.txt")

#actual call to the R script, Note: I had to supply an absolute path to Rscript
subprocess.check_call(["/Library/Frameworks/R.framework/Versions/3.5/Resources/Rscript",msgR_path, "-f", outpath])

Note: To supply an absolute path to Rscript is not perfect and as a consequence not transferable to other OS Configurations. But maybe somebody else got a clever solution for that as well (e.g. by env variables or so).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.