用rpy2在python中使用r clump

问题描述 投票:1回答:2

我的具体问题正是标题。我在python中有一个大型的光栅处理脚本,需要执行一个我在gdal / python中找不到的clump函数,也没有弄清楚如何自己“编写”。我一直在变得越来越好python仍然是新的,但我正在学习R来完成这项任务。 (已安装R版本3.4.1(2017-06-30))

我花了一点时间学习R并通过Stackoverflow上的帮助我能够在python中安装rpy2我能够执行rpy2的几个'测试'。让rpy2响应的最有用的信息是确定你的py在你的python会话或脚本中的位置。来自另一个Stack答案。如下:

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'

但是,文档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'

然而:

import rpy2.robjects as robjects
pi = robjects.r['pi']
pi[0]

工作得很好。和我发现的一些其他rpy2.robjects测试一样。我可以创建string ='''f < - function ect'''并从python中调用它们。

如果我使用:

python -m 'rpy2.tests'

我收到以下错误。 r \ Scripts> python -m'rpy2.tests'r \ Scripts \ python.exe:没有名为'rpy2的模块

文档说明:在Python 2.6上,这应该返回所有测试都成功。我正在使用Python 2.7,我也在Python 3.3中尝试过这个。

我的clump脚本如下所示:我不希望每次运行脚本时都必须实际安装软件包名称,因为它们已经安装在我的R Home中。我想尽可能使用我的python变量。

我需要弄清楚为什么rpy2没有响应文档所指示的,或者为什么我会收到错误。然后在那之后找出正确的方法来编写我的python脚本的clump部分。

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

我发现有几种方法可以从R调用raster和clump选项,但是,如果我不能让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)

这会导致大量错误。

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

问题:在命令行和脚本中测试rpy2(两者都产生错误,但我仍然可以使用基本的rpy2

导入R包,以便每次都不安装它们

最后让我的clump脚本正确调用

如果我错过了一些基本的东西,请指出我正确的方向。谢谢大家。

python r image-processing raster rpy2
2个回答
0
投票

对于您的第一个问题,请将suite = rpy2.robjects.tests.suite()替换为suite = rpy2.tests.suite()

对于你的第三个问题(让clump正常工作),你需要使用图像在R中创建一个RasterLayer对象。我不熟悉raster包,所以我不能给你确切的步骤。

我会指出arcpy模块不是“pythonic”。通常,文件名字符串只是Python中的字符串。 arcpy使用普通字符串来表示地图图层等对象很奇怪。

在您的示例中,slope_recode只是一个字符串。这就是为什么你得到错误unable to find an inherited method for function 'clump' for signature '"character"'。这意味着slope_recode被传递给R作为一个字符值(它是),而clump函数需要一个RasterLayer对象。它不知道如何处理字符值。


0
投票

我用以下代码完成了这一切。

    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")
© www.soinside.com 2019 - 2024. All rights reserved.