rpy2 fails to import 'rgl' R package

2019-06-07 05:48发布

To load the rgl package check if the rgl package is installed in R from within python, I'm combining the recipes given in these two questions:

rpy2: check if package is installed

rpy2 importr failing with xts and quantmod

Here's the MWE I put together:

from rpy2.rinterface import RRuntimeError
from rpy2.robjects.packages import importr
utils = importr('utils')

def importr_tryhard(packname, contriburl):
    try:
        if packname == 'rlg':
            rgl = importr("rgl", robject_translations = {".rgl.abclines": "_rgl_abclines2"})
        else:
            rpack = importr(packname)
            print 'success'
    except RRuntimeError:
        print 'no pack'
        rpack = 'none'
    return rpack

packname = 'rgl'
contriburl = 'http://cran.stat.ucla.edu/'
importr_tryhard(packname, contriburl)

The above code keeps failing with the error:

rpy2.robjects.packages.LibraryError: Conflict when converting R symbol in the package "rgl" to a Python symbol (rgl.abclines -> rgl_abclines while there is already rgl_abclines)

According to the answer given in the second question linked at the beginning of this question, the line:

rgl = importr("rgl", robject_translations = {".rgl.abclines": "_rgl_abclines2"})

should take care of this error, but apparently it is not.

What am I doing wrong here?


Edit

A comment below by Spacedman made me realize there was a typo in the original question above (if packname == 'rlg' should be if packname == 'rgl'). Correcting this typo, I was able to make the code work, as follows:

from rpy2.rinterface import RRuntimeError
from rpy2.robjects.packages import importr
utils = importr('utils')

def importr_tryhard(packname, contriburl):
    try:
        if packname == 'rgl':
            rpack = importr("rgl", robject_translations = {"rgl.abclines": "rgl_abclines2",
                "rgl.attrib": "rgl_attrib2", "rgl.attrib.count": "rgl_attrib_count2",
                "rgl.bbox": "rgl_bbox2", "rgl.bg": "rgl_bg2", "rgl.clear": "rgl_clear2",
                "rgl.dev.list": "rgl_dev_list2", "rgl.getcolorcount": "rgl_getcolorcount2",
                "rgl.getmaterial": "rgl_getmaterial2", "rgl.ids": "rgl_ids2",
                "rgl.init": "rgl_init2", "rgl.light": "rgl_light2", "rgl.material": "rgl_material2",
                "rgl.pixels": "rgl_pixels2", "rgl.planes": "rgl_planes2", "rgl.pop": "rgl_pop2",
                "rgl.postscript": "rgl_postscript2", "rgl.primitive": "rgl_primitive2",
                "rgl.quit": "rgl_quit2", "rgl.selectstate": "rgl_selectstate2",
                "rgl.setMouseCallbacks": "rgl_setMouseCallbacks2", "rgl.setselectstate": "rgl_setselectstate2",
                "rgl.snapshot": "rgl_snapshot2", "rgl.spheres": "rgl_spheres2", "rgl.sprites": "rgl_sprites2",
                "rgl.surface": "rgl_surface2", "rgl.texts": "rgl_texts2", "rgl.user2window": "rgl_user2window2",
                "rgl.viewpoint": "rgl_viewpoint2", "rgl.window2user": "rgl_window2user2"})
        else:
            rpack = importr(packname)
        print 'success'
    except RRuntimeError:
        print 'no pack'
        rpack = 'none'
    return rpack

packname = 'rgl'
contriburl = 'http://cran.stat.ucla.edu/'
importr_tryhard(packname, contriburl)

So it actually works, but it's terribly cumbersome and ugly. I suggest using the code I posted in my answer below which is a far better way to check for installed packages.

Thanks Spacedman!

标签: python r rpy2
3条回答
不美不萌又怎样
2楼-- · 2019-06-07 06:39

You can't do that. The rgl package needs an OpenGL device, but running in the confines of rpy2 is more like running headless.

查看更多
SAY GOODBYE
3楼-- · 2019-06-07 06:44

I'm marking Dirk's answer as accepted because he was right. Nonetheless, I'm posting my own answer here to show how I solved this issue.

Here's the code:

from rpy2.robjects.packages import importr
utils = importr('utils')

def importr_tryhard():
    contriburl = 'http://cran.stat.ucla.edu/'   
    try:
        pack_lst = utils.installed_packages()
        rpack = list(pack_lst.rx(True, 1))
    except RRuntimeError:
        rpack = []
    return rpack

rpack = importr_tryhard()
print rpack

This will return (stored in rpack) a list of all the available packages in R.

查看更多
三岁会撩人
4楼-- · 2019-06-07 06:51

You are almost certainly not fixing all symbols creating an error. In the case of rgl, there are quite a few so may consider building the dictionary using an alternative name translation rule.

For example, changing '.' -> '_' to '.' -> '__':

from rpy2.robjects.packages import importr
base = importr('base')
base.library('rgl')
env = base.asNamespace('rgl')
d = dict()
for k in env:
    if '.' in k:
        new_k = k.replace('.',  '__')
        d[k] = new_k
rgl = importr("rgl", robject_translations=d)
查看更多
登录 后发表回答