Search code examples
pythonrpython-3.xnumpyrpy2

Error using number as argument to R function in RPy2


I am attempting to use the mutual information function from the R package tseriesChaos on a time series and find the first minimum in order to determine the optimum delay for a delay embedding of the time series. I have written the following function to accomplish this:

def determine_lag(tseries, plot):
numpser = numpy.asarray(tseries)
n = numpser.size
bins = 1 + math.log(n, 2)
z = 500 
emi = numpy.array(tseriesChaos.mutual(tseries, bins, z, plot))
x = emi[0]
it = numpy.nditer(emi)
while not it.finished:
    y = it[0]
    num = it.index
    if y > x:
        lag = num
        break
    else:
        x = y
    it.iternext()
else:
    showwarning(title='Error', message='No minimum found, delay set to 50')
    failed = True
    lag = 50
return lag, failed

where tseries is the time series as extracted by soundfile.read elsewhere and plot is either TRUE or FALSE.

When attempting to use the function, however, an error seems to occur in the translation of the arguments for the R function. The output is as follows:

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1699, in __call__
return self.func(*args)
File "/Users/BrandonPlay/Soundbed 0.3/master.py", line 177, in Start
self.lag, failed = determine_lag(self.tseries, do_plot)
File "/Users/BrandonPlay/Soundbed 0.3/master.py", line 49, in determine_lag
emi = numpy.array(tseriesChaos.mutual(tseries, bins, z, plot))
File "/Users/BrandonPlay/Library/Python/3.6/lib/python/site-packages/rpy2/robjects/functions.py", line 178, in __call__
return super(SignatureTranslatedFunction, self).__call__(*args, **kwargs)
File "/Users/BrandonPlay/Library/Python/3.6/lib/python/site-packages/rpy2/robjects/functions.py", line 102, in __call__
new_args = [conversion.py2ri(a) for a in args]
File "/Users/BrandonPlay/Library/Python/3.6/lib/python/site-packages/rpy2/robjects/functions.py", line 102, in <listcomp>
new_args = [conversion.py2ri(a) for a in args]
File "/Users/BrandonPlay/Library/Python/3.6/lib/python/site-packages/rpy2/robjects/numpy2ri.py", line 72, in numpy2ri
if not o.dtype.isnative:
AttributeError: 'float' object has no attribute 'dtype'

From what I can tell, this error occurs when the function in RPy2 which converts the arguments to R objects to pass to the R function encounters the argument z. The current setup, where z is assigned outside the function call, was in an attempt to fix the error; previously, I had simply stated the number as the argument within the function call.

I really do not even remotely understand why the argument converter should be having difficulty with a simple integer argument, especially since bins is also an integer and processes fine.

Does anybody know why this might be happening?


Solution

  • As it turns out, the problem was occurring because I had activated numpy2ri incorrectly earlier in the program, assigning it to py2ri instead of using numpy2ri.activate(), thus overwriting the normal py2ri routine which converts non-numpy objects into r objects. I discovered this in trying to fix a raft of similar errors by turning everything into numpy objects, including using numpy.array([numpy.int_(some_number)]) for simple integer arguments. Strangely, numpy2ri.activate() never worked, instead giving an error something like class function has no method activate, which is very weird given that that's how the docs tell you to do it. Eventually, I removed numpy2ri entirely and just converted the tseries numpy array directly into an R vector beforehand using tmseries = robjects.FloatVector(tseries.tolist()).