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