【问题标题】:trouble installing rpy2 on win7 (R 2.12, Python 2.5)在 win7 上安装 rpy2 时遇到问题(R 2.12,Python 2.5)
【发布时间】:2011-06-22 22:24:45
【问题描述】:

我是 Python 的新手(和一般的编程)我来自金融背景,所以请多多包涵。我刚开始使用 Python(Enthought 的 Pylab/Scipy/Numpy)和 R 进行统计分析。我正在尝试将 rpy2 安装到 Python 中以集成 R,但出现错误:

试图猜测 R 的 HOME 但没有 R PATH 中的命令。

我不确定这意味着什么。如果有用的话,我的 R.exe 的路径是“C:\Program Files\R\R-2.12.1\bin”。任何帮助将不胜感激!

这里是 setup.py 的代码

import os, os.path, sys, shutil, re, itertools
from distutils.command.build_ext import build_ext as _build_ext
from distutils.command.build import build as _build

from distutils.core import setup
from distutils.core import Extension


pack_name = 'rpy2'
pack_version = __import__('rpy').__version__


class build(_build):
    user_options = _build.user_options + \
        [
        #('r-autoconfig', None,
        # "guess all configuration paths from " +\
        #     "the R executable found in the PATH " +\
        #     "(this overrides r-home)"),
        ('r-home=', None, 
         "full path for the R home to compile against " +\
             "(see r-autoconfig for an automatic configuration)"),
        ('r-home-lib=', None,
         "full path for the R shared lib/ directory " +\
             "(<r-home>/lib otherwise)"),
        ('r-home-modules=', None,
         "full path for the R shared modules/ directory " +\
             "(<r-home>/modules otherwise)") 
        ]
    boolean_options = _build.boolean_options #+ \
        #['r-autoconfig', ]


    def initialize_options(self):
        _build.initialize_options(self)
        self.r_autoconfig = None
        self.r_home = None
        self.r_home_lib = None
        self.r_home_modules = None

class build_ext(_build_ext):
    """
    -DRPY_VERBOSE
    -DRPY_DEBUG_PRESERV
    -DRPY_DEBUG_PROMISE    : evaluation of promises
    -DRPY_DEBUG_OBJECTINIT : initialization of PySexpObject
    -DRPY_DEBUG_CONSOLE    : console I/O
    -DRPY_DEBUG_COBJECT    : SexpObject passed as a CObject
    -DRPY_DEBUG_GRDEV
    """
    user_options = _build_ext.user_options + \
        [
        #('r-autoconfig', None,
        #  "guess all configuration paths from " +\
        #      "the R executable found in the PATH " +\
        #      "(this overrides r-home)"),
        ('r-home=', None, 
         "full path for the R home to compile against " +\
             "(see r-autoconfig for an automatic configuration)"),
        ('r-home-lib=', None,
         "full path for the R shared lib/ directory" +\
             "(<r-home>/lib otherwise)"),
        ('r-home-modules=', None,
         "full path for the R shared modules/ directory" +\
             "(<r-home>/modules otherwise)")]

    boolean_options = _build_ext.boolean_options #+ \
        #['r-autoconfig', ]

    def initialize_options(self):
        _build_ext.initialize_options(self)
        self.r_autoconfig = None
        self.r_home = None
        self.r_home_lib = None
        self.r_home_modules = None

    def finalize_options(self):
        self.set_undefined_options('build',
                                   #('r_autoconfig', 'r_autoconfig'),
                                   ('r_home', 'r_home'))
        _build_ext.finalize_options(self) 
        if self.r_home is None:
            self.r_home = os.popen("R RHOME").readlines()
            if len(self.r_home) == 0:
                raise SystemExit("Error: Tried to guess R's HOME but no R command in the PATH.")

    #Twist if 'R RHOME' spits out a warning
            if self.r_home[0].startswith("WARNING"):
                self.r_home = self.r_home[1]
            else:
                self.r_home = self.r_home[0]
            #self.r_home = [self.r_home, ]

        if self.r_home is None:
            raise SystemExit("Error: --r-home not specified.")
        else:
            self.r_home = self.r_home.split(os.pathsep)

        rversions = []
        for r_home in self.r_home:
            r_home = r_home.strip()
        rversion = get_rversion(r_home)
        if cmp_version(rversion[:2], [2, 8]) == -1:
            raise SystemExit("Error: R >= 2.8 required.")
        rversions.append(rversion)

        config = RConfig()
        for about in ('--ldflags', '--cppflags', 
                      'LAPACK_LIBS', 'BLAS_LIBS'):
            config += get_rconfig(r_home, about)

        print(config.__repr__())

        self.include_dirs.extend(config._include_dirs)
        self.libraries.extend(config._libraries)
        self.library_dirs.extend(config._library_dirs)

        if self.r_home_modules is None:
            self.library_dirs.extend([os.path.join(r_home, 'modules'), ])
        else:
            self.library_dirs.extends([self.r_home_modules, ])

        #for e in self.extensions:
        #    self.extra_link_args.extra_link_args(config.extra_link_args)
        #    e.extra_compile_args.extend(extra_compile_args)

    def run(self):
        _build_ext.run(self)



def get_rversion(r_home):
    r_exec = os.path.join(r_home, 'bin', 'R')
    # Twist if Win32
    if sys.platform == "win32":
        rp = os.popen3('"'+r_exec+'" --version')[2]
    else:
        rp = os.popen('"'+r_exec+'" --version')
    rversion = rp.readline()
    #Twist if 'R RHOME' spits out a warning
    if rversion.startswith("WARNING"):
        rversion = rp.readline()
    m = re.match('^R version ([^ ]+) .+$', rversion)
    rversion = m.groups()[0]
    rversion = rversion.split('.')
    rversion[0] = int(rversion[0])
    rversion[1] = int(rversion[1])
    return rversion

def cmp_version(x, y):
    if (x[0] < y[0]):
        return -1
    if (x[0] > y[0]):
        return 1
    if (x[0] == y[0]):
        if len(x) == 1 or len(y) == 1:
            return 0
        return cmp_version(x[1:], y[1:])

class RConfig(object):
    _include_dirs = None
    _libraries = None
    _library_dirs = None 
    _extra_link_args = None
    _frameworks = None
    _framework_dirs = None
    def __init__(self,
                 include_dirs = tuple(), libraries = tuple(),
                 library_dirs = tuple(), extra_link_args = tuple(),
                 frameworks = tuple(),
                 framework_dirs = tuple()):
        for k in ('include_dirs', 'libraries', 
                  'library_dirs', 'extra_link_args'):
            v = locals()[k]
            if not isinstance(v, tuple):
                if isinstance(v, str):
                    v = [v, ]
            v = tuple(set(v))
            self.__dict__['_'+k] = v
        # frameworks are specific to OSX
        for k in ('framework_dirs', 'frameworks'):
            v = locals()[k]
            if not isinstance(v, tuple):
                if isinstance(v, str):
                    v = [v, ]
            v = tuple(set(v))
            self.__dict__['_'+k] = v
            self.__dict__['_'+'extra_link_args'] = tuple(set(v + self.__dict__['_'+'extra_link_args']))


    def __repr__(self):
        s = 'Configuration for R as a library:' + os.linesep
        s += os.linesep.join(
            ['  ' + x + ': ' + self.__dict__['_'+x].__repr__() \
                 for x in ('include_dirs', 'libraries',
                           'library_dirs', 'extra_link_args')])
        s += os.linesep + ' # OSX-specific (included in extra_link_args)' + os.linesep 
        s += os.linesep.join(
            ['  ' + x + ': ' + self.__dict__['_'+x].__repr__() \
                 for x in ('framework_dirs', 'frameworks')]
            )

        return s

    def __add__(self, config):
        assert isinstance(config, RConfig)
        res = RConfig(include_dirs = self._include_dirs + \
                          config._include_dirs,
                      libraries = self._libraries + config._libraries,
                      library_dirs = self._library_dirs + \
                          config._library_dirs,
                      extra_link_args = self._extra_link_args + \
                          config._extra_link_args)
        return res
    @staticmethod
    def from_string(string, allow_empty = False):
        possible_patterns = ('^-L(?P<library_dirs>[^ ]+)$',
                             '^-l(?P<libraries>[^ ]+)$',
                             '^-I(?P<include_dirs>[^ ]+)$',
                             '^(?P<framework_dirs>-F[^ ]+?)$',
                             '^(?P<frameworks>-framework [^ ]+)$')
        pp = [re.compile(x) for x in possible_patterns]
        # sanity check of what is returned into rconfig
        rconfig_m = None        
        span = (0, 0)
        rc = RConfig()
        for substring in re.split('(?<!-framework) ', string):
            ok = False
            for pattern in pp:
                rconfig_m = pattern.match(substring)
                if rconfig_m is not None:
                    rc += RConfig(**rconfig_m.groupdict())
                    span = rconfig_m.span()
                    ok = True
                    break
                elif rconfig_m is None:
                    if allow_empty and (rconfig == ''):
                        print(cmd + '\nreturned an empty string.\n')
                        rc += RConfig()
                        ok = True
                        break
                    else:
                        # if the configuration points to an existing library, 
                        # use it
                        if os.path.exists(string):
                            rc += RConfig(library = substring)
                            ok = True
                            break
            if not ok:
                raise ValueError('Invalid substring\n' + substring 
                                 + '\nin string\n' + string)
        return rc

def get_rconfig(r_home, about, allow_empty = False):
    r_exec = os.path.join(r_home, 'bin', 'R')
    cmd = '"'+r_exec+'" CMD config '+about
    rp = os.popen(cmd)
    rconfig = rp.readline()
    #Twist if 'R RHOME' spits out a warning
    if rconfig.startswith("WARNING"):
        rconfig = rp.readline()
    rconfig = rconfig.strip()
    rc = RConfig.from_string(rconfig)
    return rc


def getRinterface_ext():
    #r_libs = [os.path.join(RHOME, 'lib'), os.path.join(RHOME, 'modules')]
    r_libs = []
    extra_link_args = []

    #FIXME: crude way (will break in many cases)
    #check how to get how to have a configure step
    define_macros = []

    if sys.platform == 'win32':
        define_macros.append(('Win32', 1))
    else:
        define_macros.append(('R_INTERFACE_PTRS', 1))
        define_macros.append(('HAVE_POSIX_SIGJMP', 1))

    define_macros.append(('CSTACK_DEFNS', 1))
    define_macros.append(('RIF_HAS_RSIGHAND', 1))

    include_dirs = []

    rinterface_ext = Extension(
            name = pack_name + '.rinterface.rinterface',
            sources = [ \
            #os.path.join('rpy', 'rinterface', 'embeddedr.c'), 
            #os.path.join('rpy', 'rinterface', 'r_utils.c'),
            #os.path.join('rpy', 'rinterface', 'buffer.c'),
            #os.path.join('rpy', 'rinterface', 'sequence.c'),
            #os.path.join('rpy', 'rinterface', 'sexp.c'),
            os.path.join('rpy', 'rinterface', 'rinterface.c')
                       ],
            depends = [os.path.join('rpy', 'rinterface', 'embeddedr.h'), 
                       os.path.join('rpy', 'rinterface', 'r_utils.h'),
                       os.path.join('rpy', 'rinterface', 'buffer.h'),
                       os.path.join('rpy', 'rinterface', 'sequence.h'),
                       os.path.join('rpy', 'rinterface', 'sexp.h'),
                       os.path.join('rpy', 'rinterface', 'rpy_rinterface.h')
                       ],
            include_dirs = [os.path.join('rpy', 'rinterface'),] + include_dirs,
            libraries = ['R', ],
            library_dirs = r_libs,
            define_macros = define_macros,
            runtime_library_dirs = r_libs,
            #extra_compile_args=['-O0', '-g'],
            #extra_link_args = extra_link_args
            )

    rpy_device_ext = Extension(
        pack_name + '.rinterface.rpy_device',
            [
            os.path.join('rpy', 'rinterface', 'rpy_device.c'),
             ],
            include_dirs = include_dirs + 
                            [os.path.join('rpy', 'rinterface'), ],
            libraries = ['R', ],
            library_dirs = r_libs,
            define_macros = define_macros,
            runtime_library_dirs = r_libs,
            #extra_compile_args=['-O0', '-g'],
            extra_link_args = extra_link_args
        )

    return [rinterface_ext, rpy_device_ext]


rinterface_exts = []
ri_ext = getRinterface_ext()
rinterface_exts.append(ri_ext)

pack_dir = {pack_name: 'rpy'}

import distutils.command.install
for scheme in distutils.command.install.INSTALL_SCHEMES.values():
    scheme['data'] = scheme['purelib']

setup(
    #install_requires=['distribute'],
    cmdclass = {'build': build,
                'build_ext': build_ext},
    name = pack_name,
    version = pack_version,
    description = "Python interface to the R language",
    url = "http://rpy.sourceforge.net",
    license = "AGPLv3.0 (except rpy2.rinterface: LGPL)",
    author = "Laurent Gautier",
    author_email = "lgautier@gmail.com",
    ext_modules = rinterface_exts[0],
    package_dir = pack_dir,
    packages = [pack_name,
                pack_name + '.rlike',
                pack_name + '.rlike.tests',
                pack_name + '.rinterface',
                pack_name + '.rinterface.tests',
                pack_name + '.robjects',
                pack_name + '.robjects.tests',
                pack_name + '.robjects.lib',
                ],
    classifiers = ['Programming Language :: Python',
                   'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
                   'License :: OSI Approved :: GNU Affero General Public License v3',
                   'Intended Audience :: Developers',
                   'Intended Audience :: Science/Research',
                   'Development Status :: 5 - Production/Stable'
                   ],
    data_files = [(os.path.join('rpy2', 'images'), 
                   [os.path.join('doc', 'source', 'rpy2_logo.png')])]

    #[pack_name + '.rinterface_' + x for x in rinterface_rversions] + \
        #[pack_name + '.rinterface_' + x + '.tests' for x in rinterface_rversions]
    )

【问题讨论】:

  • @Taj - 我遇到了在我的路径中查找 R 的类似问题(与 python 无关),我最终不得不再下一个目录进入 C:\Program Files\R\R-2.12.1\bin\x64 以让我的脚本找到 R。如果您想要 R 的 32 位版本,请将 x64 更改为 i386,看看是否可以正常工作。
  • @Taj:这意味着 R 的目录不在您的 PATH 环境变量中。请参阅此处在 Windows 上设置 PATH:computerhope.com/issues/ch000549.htm(我应该补充一点,rpy2 的主要开发人员不使用 Windows,因此您可能使用的是旧版本)。
  • @Thomas:感谢您的链接。我在之前搜索答案时发现了该信息,但是我所有修改 PATH 变量的尝试都产生了相同的结果。我尝试了 R.exe 所在的目录,R.dll 所在的目录,但没有运气。你会不会有更具体的信息?
  • @Taj:你从哪里得到rpy2,你下载的是什么版本?
  • @Taj - 查看我关于如何修改环境路径以便工作的评论。您可以通过打开命令提示符(开始 --> 运行 --> cmd)并输入 R 来确定这是 rpy2 问题还是路径问题。您应该会在 DOS 提示符下看到 R 作为一个功能齐全的程序启动。您可以从那里进行调试。

标签: python r windows-7 matplotlib rpy2


【解决方案1】:

我知道我参加聚会有点晚了,但我遇到了同样的问题,并通过 conda 进行安装使其在 Windows 7 上运行

conda install --channel https://conda.binstar.org/joshadel rpy2

【讨论】:

  • 这对我有用,我认为比上述方法更严格。
  • 是的,这对我也有用 - 谢谢!值得一提的是,“conda install”命令仅适用于 python 的 anaconda 发行版。
  • 如果我的一天没有完全浪费,我可以补充一点,这仅适用于 rpy2 2.3.9 并且getting up to date (2.7.0) 在撰写本文时有问题或不可能。但是 2.3.9 似乎可以工作!
【解决方案2】:

从源代码最终使 rpy2 与 Windows 7 一起工作。如果它不适合你,就像它不适合我一样。见rpy2 install on windows 7

希望这会有所帮助!

【讨论】:

    【解决方案3】:

    我在 win32 "WINBLOW :)" XP 下的 python 中运行 rpy2 时遇到了完全相同的问题;但我得到了这个工作,终于!

    我是这样做的:

    1. 和 Guillaume 一样,我必须将所有文件从 C:\Program Files\R\R-2.15.0\bin\i386 复制到 R\R-2.15.0

    2. 我必须设置一个环境变量

    转到我的电脑>属性>高级>环境变量> 变量:“PATH”,在“Value”末尾添加;C:\Program Files\R\R-2.15.0

    1. 在命令提示符C:\Python27\rpy2&gt;下重新运行python setup.py build install

    希望对您有所帮助,如果这对您有用,请告诉我。

    【讨论】:

      【解决方案4】:

      我遇到了一个有点不同但相关的安装问题,终于在http://www.mail-archive.com/rpy-list@lists.sourceforge.net/msg02817.html找到了解决方案

      在我通过 rpy2-2.0.8.win32-py2.6.msi 安装 rpy2 2.0.8(windows 7(64 位)、python 2.6、R 2.14(32 位和 64 位,通过 RAndFriendsSetup2140V3.2-1-1 .exe)),并尝试在 python 控制台中导入 rpy2,但出现异常:

      无法找到 R.dll

      将以下行添加到 rinterface/__init__.py 使其工作:

      if os.path.exists(os.path.join(R_HOME, 'lib')):             ## ADDED ##
          os.environ['PATH'] += ';' + os.path.join(R_HOME, 'bin')
          os.environ['PATH'] += ';' + os.path.join(R_HOME, 'modules')
          os.environ['PATH'] += ';' + os.path.join(R_HOME, 'lib')
      else:                                   ## ADDED ##
          os.environ['PATH'] += ';' + os.path.join(R_HOME, 'bin', 'i386')     ## ADDED ##
          os.environ['PATH'] += ';' + os.path.join(R_HOME, 'modules', 'i386') ## ADDED ##
          os.environ['PATH'] += ';' + os.path.join(R_HOME, 'library')     ## ADDED ##
      
      # Load the R dll using the explicit path
      # First try the bin dir:
      Rlib = os.path.join(R_HOME, 'bin', 'R.dll')
      # Try bin/i386 subdirectory seen in R 2.12.0                ## ADDED ##
      if not os.path.exists(Rlib):                        ## ADDED ##
          Rlib = os.path.join(R_HOME, 'bin', 'i386', 'R.dll')         ## ADDED ##
      # Then the lib dir:
      if not os.path.exists(Rlib):
          Rlib = os.path.join(R_HOME, 'lib', 'R.dll')
      # Otherwise fail out!
      if not os.path.exists(Rlib):
          raise RuntimeError("Unable to locate R.dll within %s" % R_HOME)
      

      事实证明,R.dll 已移动,但 __init__.py 并未相应更新。因此,只需编辑 __init__.py 文件即可。

      然后我尝试复制 Taj G 的情况,我做到了。 将“your_R_installation_dir\bin\i386”添加到windows环境变量PATH后,旧的错误消失了,但新的错误来了:

      ValueError:字符串中的子字符串无效

      似乎需要安装一些额外的部件,并且需要正确配置 C/C++ 编译器。我放弃了这里。在 windows 上使用 easy_install 从源代码构建 rpy2 似乎非常棘手,目前还没有官方支持。

      虽然 rpy2 2.0.8 与 2.2.4 相比不是一个成熟的版本,但它是 sourceforge 上带有标准 windows 安装程序的最新版本。目前,这是一个简单的选择。

      【讨论】:

        【解决方案5】:

        我在尝试将 rpy2 与 R 2.12 和 Python 2.6 一起使用时遇到了类似的问题(按照 rpy2 文档的建议)。

        似乎来自http://cran.r-project.org/bin/windows/base/R-2.12.1-win.exe 的 Windows 二进制文件将所需的 R.dll 安装在 rpy2 不期望的目录中。

        我已将所有文件从 R\R-2.12.1\bin\i386 复制到 bin 目录,设置环境变量 R_HOME 指向 R\R-2.12.1,然后它就可以工作了。

        【讨论】:

          【解决方案6】:

          我也遇到了 RPy2 的问题,但在尝试了各种不同的解决方案之后,我从未真正让它发挥作用。我鼓励你尝试人们告诉你的所有好主意,我很想看看它们是否有效!

          如果您像我一样失败,您可以根据您的目的通过以下方式使用解决方法:

          1. 使用您想要使用的所有函数编写 R 代码,同时调用您想要使用的库。将所有这些函数和库调用放入一个文件 (temp.r)。例如,也许我的文件看起来像

            
            CurrentYear <- function(birth.year,age) { 
               year <- birth.year + age
               return(year)
            }
            
          2. 使用 python 提示用户输入以执行函数调用。我是用 GUI 做的,你可以在终端用脚本来做。

          3. 使用 python 创建带有 R 函数调用的字符串。例如,我们可能有

             stuff = '\nCurrentYear("%(birth.year)d", "%(age)d")\n' %vars() 
            其中birth.yearage 已由用户在python 程序中输入。
          4. 使用python将stuff添加到temp.r的末尾:

            
            # Creates a copy of temp.r, so as not to disturb its contents for future use.
            tocall = copyfile("C:\My Documents\temp.r", "C:\My Documents\tocall.r")
            # Open the copy with the intent to append it (hence the "a")
            inp = open("C:\tocall.r", "a")
            # Adds the function call to the R script
            inp.write(stuff)
            inp.close()
            # Navigate to the correct directory, use "Rscript" to
            # run the code in the shell
            dostuff = call('cd C:\My Documents &Rscript temp.r', shell = True)
            
          5. 利润

          我不确定这种方法有什么缺点,但它对我有用。如果您在整个 RPy2 事情上失败了,希望这会有所帮助!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-07-18
            • 1970-01-01
            • 2016-02-24
            • 1970-01-01
            • 2018-09-24
            • 1970-01-01
            • 2022-01-03
            相关资源
            最近更新 更多