Error starting Python code from R with rPithon package

I would like to run this Python code from R:

>>> import nlmpy >>> nlm = nlmpy.mpd(nRow=50, nCol=50, h=0.75) >>> nlmpy.exportASCIIGrid("raster.asc", nlm) 

Nlmpy is a Python package for creating neutral landscape models. Example presented website

To run this Python code from R, I am trying to use the rPithon package. However, I get this error message:

 if (pithon.available()) { nRow <- 50 nCol <- 50 h <- 0.75 # this file contains the definition of function concat pithon.load("C:/Users/Anaconda2/Lib/site-packages/nlmpy/nlmpy.py") pithon.call( "mpd", nRow, nCol, h) } else { print("Unable to execute python") } Error in pithon.get("_r_call_return", instance.name = instname) : Couldn't retrieve variable: Traceback (most recent call last): File "C:/Users/Documents/R/win-library/3.3/rPithon/pythonwrapperscript.py", line 110, in <module> reallyReallyLongAndUnnecessaryPrefix.data = json.dumps([eval(reallyReallyLongAndUnnecessaryPrefix.argData)]) File "C:\Users\ANACON~1\lib\json\__init__.py", line 244, in dumps return _default_encoder.encode(obj) File "C:\Users\ANACON~1\lib\json\encoder.py", line 207, in encode chunks = self.iterencode(o, _one_shot=True) File "C:\Users\ANACON~1\lib\json\encoder.py", line 270, in iterencode return _iterencode(o, 0) File "C:\Users\ANACON~1\lib\json\encoder.py", line 184, in default raise TypeError(repr(o) + " is not JSON serializable") TypeError: array([[ 0.36534654, 0.31962481, 0.44229946, ..., 0.11513079, 0.07156331, 0.00286971], [ 0.41534291, 0.41333479, 0.48118995, ..., 0.19203674, 0.04192771, 0.03679473], [ 0.5188 

Is this error causing syntax in my code? I work with the Anaconda 4.2.0 platform for Windows, which uses Python 2.7.

+2
r rpython
source share
2 answers

I have not used the nlmpy package, therefore, I am not sure what your expected result will be. However, this code successfully binds between R and Python.

There are two files,

nlmpyInR.R

 command ="python" path2script="path_to_your_pythoncode/nlmpyInPython.py" nRow <-50 nCol <-50 h <- 0.75 # Build up args in a vector args = c(nRow, nCol, h) # Add path to script as first arg allArgs = c(path2script, args) Routput = system2(command, args=allArgs, stdout=TRUE) #The command would be python nlmpyInPython.py 50 50 0.75 print(paste("The Output is:\n", Routput)) 

nlmpyInPython.py

 import sys import nlmpy #Getting the arguments from the command line call nRow = sys.argv[1] nCol = sys.argv[2] h = sys.argv[3] nlm = nlmpy.mpd(nRow, nCol, h) pyhtonOutput = nlmpy.exportASCIIGrid("raster.asc", nlm) #Whatever you print will get stored in the R output variable. print pyhtonOutput 
+2
source share

The cause of the error you are getting is "is not serializable JSON". Your R code calls mpd functions with specific arguments, and this function will execute correctly. Then the rPithon library will try to send return the value of the function back to R, and for this it will try to create a JSON object that describes the return value.

This works well for integers, floating point values, arrays, etc. but not every kind of Python object can be converted to such JSON. And since rPithon cannot convert the return value of mpd in this way, an error is generated.

You can still use rPithon to call the mpd function. The following code creates a new Python function that takes two steps: first, it calls the mpd function with the specified parameters, and then exports the result to a file from which the file name is also an argument. Using rPithon, the new function is then called from R. Since myFunction returns nothing, presenting the return value in JSON format will not be a problem.

 library("rPithon") pythonCode = paste("import nlmpy.nlmpy as nlmpy", "", "def myFunction(nRow, nCol, h, fileName):", " nlm = nlmpy.mpd(nRow, nCol, h)", " nlmpy.exportASCIIGrid(fileName, nlm)", sep = "\n") pithon.exec(pythonCode) nRow <- 50 nCol <- 50 h <- 0.75 pithon.call("myFunction", nRow, nCol, h, "outputraster.asc") 

Here's the Python code, defined as an R string, and executed using pithon.exec . You can also put this Python code in a separate file and use pithon.load to process the code so that myFunction function is known.

0
source share

All Articles