Search code examples
rpy2

rpy2: How to return vector to R from Python callback function?


I'm trying to call a function in an R package from Python. The R function requires a callback function that takes a vector of values, does some calculations, and returns a result vector.

I'm able to get a callback working, but only if it returns a scalar. All attempts to return more than one value result in rpy2 throwing a ValueError.

From rpy2.robject, I have tried FloatVectors and IntVectors. I have also tried converting my Python list to a numpy array or pandas dataframe and then using rpy2's interfaces for converting these. None work.

To be clear, I'm able to use all of these methods successfully to create objects that I can pass from Python to the argument list of an R function. I only get the error when I'm trying to return a vector from a Python callback.

I've distilled the problem down to a simple test. Here is the R code that accepts and then calls the callback function:

Test <-
function(cb) {
    cb()
}

And, here is the Python code that I'm using to call the R code:

import rpy2.rinterface as ri
from rpy2 import robjects

robjects.r('source("Test.R")')
test = robjects.r['Test']

@ri.rternalize
def cb_test():

    return robjects.FloatVector([1.0, 2.0, 3.0])

test(cb_test)

Expected result:

FloatVector with 3 elements.
1.000000    2.000000    3.000000

Actual result:

<class 'ValueError'>: [1] 1 2 3

Thanks in advance to anyone who can figure out what I'm doing wrong.


Solution

  • The issue can also be reproduced with simply:

    import rpy2.rinterface as ri
    ri.initr()
    
    @ri.rternalize
    def cb_test():
        return ri.FloatSexpVector([1.0, 2.0, 3.0])
    
    cb_test()
    

    This is seems to be an issue, now tracked here: https://bitbucket.org/rpy2/rpy2/issues/538/

    Edit: there is an initial fix in the code repos, and bugfix release of rpy2 will normally be made over the weekend.