PyWPS with R

The following shows how you can wrap R software with PyWPS.

Rpy2

There’s several R-to-python Python libraries but Rpy2 is probably the most well documented and most frequently used. As long as it is installed, a R library can be accessed with importr([package-name]). Since R base and utils are installed with rpy2 you can import them:

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

Then you can use functions from that package with package.function_name(). If the R function name has a period . it is replaced with an underscore _ in python.

base.all(True)
base.all_equal("hello","world") # all.equal() in R

You can execute any regular R code as a string passed to robjects.r()

from rpy2 import robjects
count = robjects.r("c(1,2,3)")
robjects.r("all(T)")

You can also access R functions with the syntax robjects.r["function.name"] if you want to avoid the import step.

robjects.r["save"](count, file=output_path)

Install another package with Rpy2 and use the functions form that package…

utils.install_packages("climdex.pcic")
climdex_pcic = importr("climdex.pcic")
climdex_pcic.climdex_gsl(climdexInput, gsl_mode)

I/O

Rpy2 handles R-to-python conversions of LITERAL_DATA_TYPES, but objects of other types may need to be stored in a RDS or Rdata file. RDS files and Rdata files are indistinguishable by mime type when read to the server so their handling has to be done elsewhere in the processes. You can see how it’s handled in PCIC’s quail. Read the file as a ComplexInput with format:

from pywps import ComplexInput, Format

ComplexInput(
   "r_file",
   "R data file",
   supported_formats=[Format("application/x-gzip", encoding="base64")],
)

… And if your output is an R object you can save that object to an RDS or Rdata file and return it with ComplexOutput:

from pywps import ComplexOutput

ComplexOutput(
  "r_output",
  "R output file",
  supported_formats=[Format("application/x-gzip", extension=".rda", encoding="base64")],
)

Installing Dependencies

You can write a simple script in R, bash, or Python to automate installation of R package dependencies. devtools::install_version() is used to pin versions in PCIC’s quail and chickadee. You can take a look at the R script here.

The script reads from a file similar to requirements.txt for Python dependencies:

r_requirements.txt:

PCICt==0.5.4.1
climdex.pcic==1.1.11

Dockerfile

To install Rpy2, R needs to be installed already. A good base image for R is rocker/r-ver and you can install Python on top of it. Check out the pcic/quail Dockerfile as an example.