0

There are a lot of related answers on SO, but all of them use the high-level robjects interface provided by rpy2. But, if I wanted to use the low-level interface, how do I go about it? Following is a MCVE (provided you have the package copula installed in R):

Alternative 1, using just the low-level interface as in the docs

import numpy as np
from rpy2 import rinterface as ri

ri.initr()

def rimport(packname):
    as_environment = ri.baseenv['as.environment']
    require = ri.baseenv['require']
    require(ri.StrSexpVector([packname]),
            quiet = ri.BoolSexpVector((True, )))
    packname = ri.StrSexpVector(['package:' + str(packname)])
    pack_env = as_environment(packname)
    return pack_env

Copula = rimport('copula')

# The ri.SexpVector line causes the problem, but this is how the docs has it.
gc = Copula['gofCopula'](copula=Copula['gumbelCopula'](dim=5),
                         x=ri.SexpVector(np.random.randn(100,5), ri.REALSXP),
                         N=ri.IntSexpVector((1000,)),
                         simulation=ri.StrSexpVector(('mult',)))
Dies with:
RRuntimeError                             Traceback (most recent call last)
<ipython-input-3-63487c32d528> in <module>()
      2                          x=ri.SexpVector(np.random.randn(100,5), ri.REALSXP),
      3                          N=ri.IntSexpVector((1000,)),
----> 4                          simulation=ri.StrSexpVector(('mult',)))
      5 
      6 gc

RRuntimeError: Error: (d <- ncol(x)) > 1 is not TRUE

Alternative 2, using numpy2ri, as shown in all answers on SO

import numpy as np
from rpy2 import rinterface as ri
from rpy2.robjects import numpy2ri

ri.initr()
numpy2ri.activate()

def rimport(packname):
    as_environment = ri.baseenv['as.environment']
    require = ri.baseenv['require']
    require(ri.StrSexpVector([packname]),
            quiet = ri.BoolSexpVector((True, )))
    packname = ri.StrSexpVector(['package:' + str(packname)])
    pack_env = as_environment(packname)
    return pack_env

Copula = rimport('copula')

# Automatic conversion does not happen!
gc = Copula['gofCopula'](copula=Copula['gumbelCopula'](dim=5),
                         x=np.random.randn(100,5), # Hoping for automatic conversion
                         N=ri.IntSexpVector((1000,)),
                         simulation=ri.StrSexpVector(('mult',)))
Dies with:
ValueError                                Traceback (most recent call last)
<ipython-input-1-17b2b5105f01> in <module>()
     24                          x=np.random.randn(100,5),
     25                          N=ri.IntSexpVector((1000,)),
---> 26                          simulation=ri.StrSexpVector(('mult',)))
     27 
     28 gc

ValueError: All parameters must be of type Sexp_Type,or Python int/long, float, bool, or None

Alternative 3, using both together

Dies just like Alternative 1.


Additional Notes

1)

list(ri.SexpVector(np.random.randn(100,5), ri.REALSXP))

Is a list that contains NA_real_, exactly 100 of them.

2)

If I ditch the low-level interface, and just use the high-level interface, everything works fine. But that is not what I am looking for.

import numpy as np
from rpy2.robjects.packages import importr
from rpy2.robjects import numpy2ri

numpy2ri.activate()

Copula = importr('copula')
gc = Copula.gofCopula(copula=partial(Copula.gumbelCopula, dim=5)(),
                      x=np.random.randn(100,5),
                      N=1000,
                      simulation='mult')

1 Answer 1

1

Thanks for your praise of the high-level interface and the work that went into it, although an implicit one: it is indeed designed to "just work".

The low-level interface is quite close to R's C-level API and its use may require more knowledge about it that would deem reasonable to expect from a Python audience. Note that the documentation published is unfortunately not complete because the docstrings are not included (issue with readthedocs).

I'd encourage you to use the high-level interface unless a specific reason not to, but since the source is open what is happening in the converter can be checked easily (it is here).

Sign up to request clarification or add additional context in comments.

2 Comments

Hello again, Igautier! I hope you've been doing great. In the discussion following your answer before, we found some limitations with the high-level interface and multiprocessing. I usually work with large datasets, and, unfortunately, a lot of great statistical packages have no equivalent in Python (copula being one of them). So I must use R. It takes about 14 hours to fit a copula model to one subset of my data, of which I have 28. So, parallel is the way to go. Hence, I am looking to use the low-level interface which works with multiprocessing
The real question I have is, how to convert numpy array to R matrix, while preserving the shape of the array, using the low-level rinterface. Although the high-level api is amazing, and I really appreciate all the great work that has gone into making it, it does not solve my specific problem. Thank you for pointing out the exact location for numpy2ri in the source. That was very helpful to replicate in my scripts.

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.