Ошибка при запуске кода Python из R с пакетом rPithon

Я хотел бы запустить этот код Python из R:

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

Nlmpy — это пакет Python для создания нейтральных моделей ландшафта. Пример взят с веб-сайта.

Чтобы запустить этот код Python из R, я пытаюсь использовать пакет rPithon. . Однако я получаю это сообщение об ошибке:

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

Эта ошибка вызвана ошибкой синтаксиса в моем коде? Я работаю с платформой Anaconda 4.2.0 для Windows, которая использует версию Python 2.7.


person Nell    schedule 18.11.2016    source источник
comment
Функция mpd в python возвращает двумерный массив, который по умолчанию не поддерживается JSONEncoder. В Python выполните import json help(json.encoder), чтобы увидеть больше информации. Кроме того, этот пост, похоже, связан с stackoverflow. ком/вопросы/22281059/   -  person jmuhlenkamp    schedule 22.11.2016
comment
Насколько вы полны решимости использовать пакет rPithon? Готовы ли вы использовать некоторые другие подходы, которые вызывают функции Python из R?   -  person Ronak Shah    schedule 23.11.2016
comment
Почему бы не вызвать скрипт Python в командной строке с аргументами, используя R system()?   -  person Parfait    schedule 24.11.2016
comment
Большое спасибо за ваши ответы. Я не знаю system() или других подходов к вызову функций Python из R.   -  person Nell    schedule 24.11.2016


Ответы (2)


Я не использовал пакет nlmpy, поэтому я не уверен, каким будет ваш ожидаемый результат. Однако этот код успешно взаимодействует между R и Python.

Есть два файла,

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

нлмпиинпитон.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's output variable. 
print pyhtonOutput
person Ronak Shah    schedule 24.11.2016
comment
Большое спасибо за ваш ответ! У меня появляется сообщение об ошибке, когда я запускаю код из R (код в nlmpylnPython.py работает в Python): running command '"python" C:/nlmpyInPython.py 50 50 0.75' had status [1] "Traceback (most recent call last):" [2] " File \"C:/nlmpyInPython.py\", line 14, in <module>" [3] " nlm = nlmpy.mpd(nRow, nCol, h) " [4] " File \"C:\\Users\\ANACON~1\\lib\\site-packages\\nlmpy\\nlmpy.py\", line 523, in mpd" - person Nell; 30.11.2016
comment
Остальная часть сообщения об ошибке [5] " mask = np.ones((nRow, nCol)) " [6] " File \"C:\\Users\\ANACON~1\\lib\\site-packages\\numpy\\core\\numeric.py\", line 190, in ones" [7] " a = empty(shape, dtype, order)" [8] "TypeError: an integer is required" attr(,"status") [1] 1 - person Nell; 30.11.2016
comment
@Nell Я запустил свою систему Windows, и она работала нормально. Вызов python кажется немного сомнительным. почему это '"python" C:/nlmpyInPython.py 50 50 0.75'? Скорее не должно быть python C:/nlmpyInPython.py 50 50 0.75 ? Похоже, числа 50 50 0.75 идут как строка. - person Ronak Shah; 30.11.2016
comment
Я проверил, что nRow, nCol и h являются числами, используя класс (nRow) в R. Все эти аргументы являются числовыми. Я также проверил путь Python, запустив command="C:/Users/Anaconda2/python.exe" вместо command="python". У меня снова такое же сообщение об ошибке. - person Nell; 30.11.2016
comment
Можете ли вы запустить python C:/nlmpyInPython.py 50 50 0.75 из командной строки и проверить, правильно ли он работает? - person Ronak Shah; 01.12.2016
comment
Большое спасибо за твою помощь. Наконец, скрипт R работает, когда я указываю nRow = int(sys.argv.[1]), nCol = int(sys.argv.[2]) и h = float(sys.argv.[3]). Однако я хотел бы запустить другую функцию nlm1 = nlmpy.classifyArray(nlm, [1, 1, 1]) в сценарии Python, но я не знаю, как определить список [1, 1, 1] в аргументах функции system2()? Большое спасибо за ваше время. - person Nell; 03.12.2016
comment
Может быть, вы можете отправить элементы списка отдельно от R? a=1, b=1 и c=1, а затем в Python используйте nlm1 = nlmpy.classifyArray(nlm, [sys.argv[4], sys.argv[5], sys.argv[6]])? - person Ronak Shah; 03.12.2016
comment
Большое спасибо за твою помощь. Это хорошая идея ! Я получаю это сообщение об ошибке: [1] "Traceback (most recent call last):" [2] " File \"C:/nlmpyInPython.py\", line 34, in <module>" [3] " nlm1= nlmpy.classifyArray(nlm, [a, b, c])" [4] " File \"C:\\Users\\ANACON~1\\lib\\site-packages\\nlmpy\\nlmpy.py\", line 233, in classifyArray" [5] " cumulativeProportions = w2cp(weights)" - person Nell; 09.12.2016

На причину ошибки, которую вы получаете, намекает строка «не сериализуема JSON». Ваш код R вызывает функцию mpd с определенными аргументами, и сама эта функция будет выполняться правильно. Затем библиотека rPithon попытается отправить возвращаемое значение функции обратно в R, и для этого она попытается создать JSON объект, описывающий возвращаемое значение.

Это хорошо работает для целых чисел, значений с плавающей запятой, массивов и т. д., но не каждый объект Python можно преобразовать в такое представление JSON. И поскольку rPithon не может преобразовать возвращаемое значение mpd таким образом, генерируется ошибка.

Однако вы все еще можете использовать rPithon для вызова функции mpd. Следующий код создает новую функцию Python, которая выполняет два шага: сначала она вызывает функцию mpd с указанными параметрами, а затем экспортирует результат в файл, имя файла которого также является аргументом. Используя rPithon, новая функция затем вызывается из R. Поскольку myFunction ничего не возвращает, представление возвращаемого значения в формате JSON не будет проблемой.

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

Здесь код Python, определенный как строка R и выполненный с использованием pithon.exec. Вы также можете поместить этот код Python в отдельный файл и использовать pithon.load для обработки кода, чтобы функция myFunction была известна.

person brm    schedule 30.04.2017