[英]R clump within python with rpy2
My specific issue is exactly the title. 我的具体问题就是标题。 I have a large raster processing script in python and need to perform a clump function which I cannot find in gdal / python nor have I figured out how to 'write it' myself. 我在python中有一个大型的栅格处理脚本,并且需要执行我在gdal / python中找不到的丛集函数,也没有想出如何自己“编写”它。 I am becoming better with python all the time just still newish, but am learning R for this task. 我一直都在使用python不断变得更好,但是正在为该任务学习R。 (installed R version 3.4.1 (2017-06-30)) (已安装R版本3.4.1(2017-06-30))
I am able to get rpy2 installed within python after spending a little time learning R and through help on Stackoverflow I have been able to perform several 'tests' of rpy2. 花一点时间学习R之后,我就能在python中安装rpy2,并且通过Stackoverflow的帮助,我已经能够执行rpy2的多个“测试”。 The most helpful info in getting rpy2 to respond was to establish where your R is within your python session or script. 使rpy2响应最有用的信息是确定R在python会话或脚本中的位置。 from another Stack answer. 从另一个堆栈答案。 As below: 如下:
import os
os.environ['PYTHONHOME'] = r'C:\Python27\ArcGIS10.3\Scripts\new_ve_folder\Scripts'
os.environ['PYTHONPATH'] = r'C:\Python27\ArcGIS10.3\Scripts\new_ve_folder\Lib\site-packages'
os.environ['R_HOME'] = r'C:\Program Files\R\R-3.4.1'
os.environ['R_USER'] = r'C:\Python27\ArcGIS10.3\Scripts\new_ve_folder\Lib\site-packages\rpy2'
However, the main tests listed in the documentation http://rpy.sourceforge.net/rpy2/doc-2.1/html/overview.html I cannot get to work. 但是,文档http://rpy.sourceforge.net/rpy2/doc-2.1/html/overview.html中列出的主要测试我无法使用。
import rpy2.robjects.tests
import unittest
# the verbosity level can be increased if needed
tr = unittest.TextTestRunner(verbosity = 1)
suite = rpy2.robjects.tests.suite()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'suite'
However: 然而:
import rpy2.robjects as robjects
pi = robjects.r['pi']
pi[0]
works just fine. 效果很好。 as do a few other rpy2.robjects tests I have found. 就像我发现的其他一些rpy2.robjects测试一样。 I can create string = ''' f <- functions ect ''' and call those from python. 我可以创建字符串='''f <-函数ect'''并从python调用它们。
If i use: 如果我使用:
python -m 'rpy2.tests'
I get the following error. 我收到以下错误。 r\\Scripts>python -m 'rpy2.tests' r\\Scripts\\python.exe: No module named 'rpy2 r \\ Scripts> python -m'rpy2.tests'r \\ Scripts \\ python.exe:没有名为'rpy2的模块
Documentation states: On Python 2.6, this should return that all tests were successful. 文档说明:在Python 2.6上,这应该返回所有测试均已成功。 I am using Python 2.7 and I also tried this in Python 3.3. 我正在使用Python 2.7,并且也在Python 3.3中进行了尝试。
My script for clump starts as below: I do not want to have to actually install the package names each time I run the script as they are already installed in my R Home. 我的丛集脚本如下所示:我不想每次运行脚本时都必须实际安装软件包名称,因为它们已经安装在R Home中。 I would like to use my python variables if possible. 如果可能,我想使用我的python变量。
I need to figure out why rpy2 does not respond as the documentation indicates, or why I am getting errors. 我需要弄清楚为什么rpy2没有按照文档中的说明进行响应,或者为什么我会出错。 And then after that figure out the correct way to write my clump portion of my python script. 然后,找出正确的方法来编写我的python脚本的聚集部分。
packageNames = ('raster', 'rgdal')
if all(rpackages.isinstalled(x) for x in packageNames):
have_packages = True
else:
have_packages = False
if not have_packages:
utils = rpackages.importr('utils')
utils.chooseCRANmirror(ind=1)
packnames_to_install = [x for x in packageNames if not rpackages.isinstalled(x)]
if len(packnames_to_install) > 0:
utils.install_packages(StrVector(packnames_to_install))
from rpy2.robjects.packages import importr
import rpy2.robjects as robjects
There are several ways I have found to call the raster and clump options from R, however, if I cannot get rpy2 to respond correctly, I am not going to get these to work at all But since several other tests work I am not positive. 我发现有几种方法可以从R调用栅格和丛集选项,但是,如果我无法使rpy2正确响应,那么我将根本无法使它们起作用。但是由于其他一些测试有效,因此我并不满意。
raster = robjects.r['raster']
raster = importr('raster')
clump = raster.clump
clump = robjects.r.clump
type(raster.clump)
tempDIR = r"C:\Users\script_out\temp"
slope_recode = os.path.join(tempDIR, "step2b_input.img")
outfile = os.path.join(tempDIR, "Rclumpfile.img")
raster.clump(slope_recode, filename=outfile, direction=4, gaps=True, format='HFA', overwrite=True)
Which results in a large amount of errors. 这会导致大量错误。
Traceback (most recent call last):
File "C:/Python27/ArcGIS10.3/Scripts/new_ve_folder/Scripts/rpy2_practice.py", line 97, in <module>
raster.clump(slope_recode, filename=outfile, direction=4, gaps=True, format='HFA', overwrite=True)
File "C:\Python27\ArcGIS10.3\Scripts\new_ve_folder\lib\site-packages\rpy2\robjects\functions.py", line 178, in __call__
return super(SignatureTranslatedFunction, self).__call__(*args, **kwargs)
File "C:\Python27\ArcGIS10.3\Scripts\new_ve_folder\lib\site-packages\rpy2\robjects\functions.py", line 106, in __call__
res = super(Function, self).__call__(*new_args, **new_kwargs)
rpy2.rinterface.RRuntimeError: Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function 'clump' for signature '"character"'
Issues: testing rpy2 in command line and script (both produce errors, but I am still able to use basic rpy2 问题:在命令行和脚本中测试rpy2(都会产生错误,但是我仍然能够使用基本的rpy2
importing the R packages so as not to install them each time 导入R软件包,以免每次都安装它们
finally getting my clump script called correctly 终于让我的丛集脚本正确调用了
If I have missed something basic, please point me in the right direction. 如果我错过了一些基本的知识,请指出正确的方向。 Thanks all. 谢谢大家
For your first problem, replace suite = rpy2.robjects.tests.suite()
with suite = rpy2.tests.suite()
. 对于第一个问题,将suite = rpy2.robjects.tests.suite()
替换为suite = rpy2.tests.suite()
。
For your third problem (getting clump
to work correctly), you need to create a RasterLayer
object in R using the image. 对于你的第三个问题(让clump
正常工作),你需要创建一个RasterLayer
使用图像中的R对象。 I'm not familiar with the raster
package, so I can't give you the exact steps. 我对raster
包不熟悉,因此无法给您确切的步骤。
I will point out the arcpy
module is not "pythonic". 我将指出arcpy
模块不是 “ pythonic”的。 Normally, strings of filenames are just strings in Python. 通常,文件名字符串只是Python中的字符串。 arcpy
is weird in using plain strings to represent objects like map layers. 使用纯字符串表示诸如地图图层之类的对象时, arcpy
很奇怪。
In your example, slope_recode
is just a string. 在您的示例中, slope_recode
只是一个字符串。 That's why you got the error unable to find an inherited method for function 'clump' for signature '"character"'
. 这就是为什么出现错误, unable to find an inherited method for function 'clump' for signature '"character"'
。 It means slope_recode
was passed to R as a character value (which it is), and the clump
function expects a RasterLayer
object. 这意味着slope_recode
传递给R作为一个字符值(它是),并且clump
函数需要RasterLayer
对象。 It doesn't know how to handle character values. 它不知道如何处理字符值。
I got this all to work with the below code. 我将所有这些都与下面的代码一起使用。
import warnings
os.environ['PATH'] = os.path.join(scriptPath, 'path\\my_VE\\R\\R-3.4.2\\bin\\x64')
os.environ['PYTHONHOME'] = os.path.join(scriptPath, 'path\\my_VE\\Scripts\\64bit')
os.environ['PYTHONPATH'] = os.path.join(scriptPath, 'path\\my_VE\\Lib\\site-packages')
os.environ['R_HOME'] = os.path.join(scriptPath, 'path\\my_VE\\R\\R-3.4.2')
os.environ['R_USER'] = os.path.join(scriptPath, 'path\\my_VE\\Scripts\\new_ve_folder\\Scripts\\rpy2')
#
import platform
z = platform.architecture()
print(z)
## above will confirm you are working on 64 bit
gc.collect()
## this code snippit will tell you which library is being Read
command = 'Rscript'
cmd = [command, '-e', ".libPaths()"]
print(cmd)
x = subprocess.Popen(cmd, shell=True)
x.wait()
import rpy2.robjects.packages as rpackages
import rpy2.robjects as robjects
from rpy2.robjects import r
import rpy2.interactive.packages
from rpy2.robjects import lib
from rpy2.robjects.lib import grid
# # grab r packages
print("loading packages from R")
## fails at this point with the following error
## Error: cannot allocate vector of size 232.6 Mb when working with large rasters
rpy2.robjects.packages.importr('raster')
rpy2.robjects.packages.importr('rgdal')
rpy2.robjects.packages.importr('sp')
rpy2.robjects.packages.importr('utils')
# rpy2.robjects.packages.importr('memory')
# rpy2.robjects.packages.importr('dplyr')
rpy2.robjects.packages.importr('data.table')
grid.activate()
# set python variables for R code names
raster = robjects.r['raster']
writeRaster = robjects.r['writeRaster']
# setwd = robjects.r['setwd']
clump = robjects.r['clump']
# head = robjects.r['head']
crs = robjects.r['crs']
dim = robjects.r['dim']
projInfo = robjects.r['projInfo']
slope_recode = os.path.join(tempDIR, "_lope_recode.img")
outfile = os.path.join(tempDIR, "Rclumpfile.img")
recode = raster(slope_recode) # this is taking the image and reading it into R raster package
## https://stackoverflow.com/questions/47399682/clear-r-memory-using-rpy2
gc.collect() # No noticeable effect on memory usage
time.sleep(2)
gc.collect() # Finally, memory usage drops
R = robjects.r
R('memory.limit()')
R('memory.limit(size = 65535)')
R('memory.limit()')
print"starting Clump with rpy2"
clump(recode, filename=outfile, direction=4, gaps="True", format="HFA")
final = raster(outfile)
final = crs("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0,-0,-0,-0,0 +no_defs")
print ("clump file created, CRS accurate, next step")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.