Comment utiliser les DataFrames pandas et les tableaux numpy dans Rpy2?

j'aimerais utiliser pandas pour toute mon analyse avec numpy mais utiliser Rpy2 pour tracer mes données. Je veux faire toutes les analyses en utilisant des bases de données pandas et ensuite utiliser le tracé complet de R via rpy2 pour tracer ceux-ci. py2,et j'utilise ipython pour tracer. Quelle est la manière correcte de le faire?

presque toutes les commandes que j'essaie échouent. Par exemple:

  • j'essaie de tracer une dispersion entre deux colonnes d'une base de données pandas df. J'aimerais que les étiquettes de df utilisé dans l'axe x/y tout comme serait utilisé si c'était une dataframe R. Est-il un moyen de faire cela? Quand j'ai essayer de le faire avec r.plot, j'obtiens ce charabia parcelle:

In: r.plot(df.a, df.b) # df is pandas DataFrame

donne:

Out: rpy2.rinterface.NULL

résultant de la parcelle:

enter image description here

comme vous pouvez le voir, les labels axes sont en désordre et il ne lit pas les labels axes de la DataFrame comme il devrait (l'axe X est colonne a de df et l'axe des Y est la colonne b).

  • Si j'essaie de faire un histogramme avec r.hist, il ne fonctionne pas du tout, ce qui donne le message d'erreur:

    In: r.hist(df.a)
    Out: 
    ...
    vectors.pyc in <genexpr>((x,))
        293         if l < 7:
        294             s = '[' + 
    --> 295                 ', '.join((p_str(x, max_width = math.floor(52 / l)) for x in self[ : 8])) +
        296                 ']'
        297         else:
    
    vectors.pyc in p_str(x, max_width)
        287                     res = x
        288                 else:
    --> 289                     res = "%s..." % (str(x[ : (max_width - 3)]))
        290             return res
        291 
    
    TypeError: slice indices must be integers or None or have an __index__ method
    

Et résultant dans cette parcelle:

enter image description here

une idée de ce que signifie l'erreur? Et là encore, les haches sont toutes abîmées et jonchées de données abjectes.

EDIT: cette erreur ne se produit que lors de l'utilisation d'ipython. Quand j'exécute la commande à partir d'un script, il produit toujours l'intrigue problématique, mais au moins fonctionne sans erreur. Il doit y avoir quelque chose de mal à appeler ces commandes depuis ipython.

  • j'ai aussi essayé de convertir la base de données pandas df pour la R DataFrame comme recommandé par l'affiche ci-dessous, mais qui ne parvient pas trop avec cette erreur:

    com.convert_to_r_dataframe(mydf) # mydf is a pandas DataFrame
    ----> 1 com.convert_to_r_dataframe(mydf)
    in convert_to_r_dataframe(df, strings_as_factors)
        275     # FIXME: This doesn't handle MultiIndex
        276 
    --> 277     for column in df:
        278         value = df[column]
        279         value_type = value.dtype.type
    
    TypeError: iteration over non-sequence
    

Comment puis-je obtenir ces fonctionnalités de pointage de base pour travailler sur une base de données Pandas (avec des étiquettes de les parcelles de lire sur les étiquettes des Pandas DataFrame), et également obtenir la conversion entre une Pandas DF pour un R DF de travail?

EDIT2: Voici un exemple complet d'un fichier csv ".txt" (http://pastebin.ca/2311928) et mon code pour répondre au commentaire de @ dale:

import rpy2
from rpy2.robjects import r
import rpy2.robjects.numpy2ri
import pandas.rpy.common as com
from rpy2.robjects.packages import importr
from rpy2.robjects.lib import grid
from rpy2.robjects.lib import ggplot2
rpy2.robjects.numpy2ri.activate()
from numpy import *
import scipy

# load up pandas df
import pandas
data = pandas.read_table("./test.txt")
# plotting a column fails
print "data.c2: ", data.c2
r.plot(data.c2)
# Conversion and then plotting also fails
r_df = com.convert_to_r_dataframe(data)
r.plot(r_df)

l'appel à tracer la colonne de " données.c2 " échoue, même si data.c2 est une colonne d'un DF pandas et par conséquent, à toutes fins pratiques et à des fins devrait être un tableau numpy. Je utilisez le activate() appeler donc j'ai pensé qu'il pourrait gérer cette colonne comme un tableau de numpy et le tracer.

le second appel à tracer la base de données data après la conversion en une base de données r échoue également. Pourquoi est-ce? Si je charge test.txt à partir de R comme un dataframe, je suis en mesure de plot() Et comme ma base de données a été convertie de pandas en R, Il semble que cela devrait fonctionner ici aussi.

Quand je fais essayer rmagic dans ipython, il ne se déclenche pas une parcelle de la fenêtre pour une raison quelconque, bien qu'il ne fait pas d'erreur. I. e. si je fais:

In [12]: X = np.array([0,1,2,3,4])

In [13]: Y = np.array([3,5,4,6,7])
In [14]: import rpy2

In [15]: from rpy2.robjects import r

In [16]: import rpy2.robjects.numpy2ri

In [17]: import pandas.rpy.common as com

In [18]: from rpy2.robjects.packages import importr

In [19]: from rpy2.robjects.lib import grid

In [20]: from rpy2.robjects.lib import ggplot2


In [21]: rpy2.robjects.numpy2ri.activate()

In [22]: from numpy import *

In [23]: import scipy

In [24]: r.assign("x", X)
Out[24]: 
<Array - Python:0x592ad88 / R:0x6110850>
[       0,        1,        2,        3,        4]

In [25]: r.assign("y", Y)
<Array - Python:0x592f5f0 / R:0x61109b8>
[       3,        5,        4,        6,        7]

In [27]: %R plot(x,y)

il n'y a pas d'erreur, mais pas de fenêtre de tracé non plus. En tout cas, j'aimerais en tenir à rpy2 et ne pas compter sur rmagic si possible.

Merci.

12
demandé sur user248237dfsf 2013-02-02 03:32:46

3 réponses

[note: votre code dans "edit 2" fonctionne ici (Python 2.7, rpy2-2.3.2, R-1.15.2).]

comme le mentionne @ dale chaque fois que les objets R sont anonymes (c'est-à-dire qu'il n'existe aucun symbole R pour l'objet) le R deparse(substitute()) finira par retourner le structure() de L'objet R, et une correction possible est de spécifier les paramètres" xlab "et" ylab"; pour certaines placettes, vous devrez aussi spécifier main (le titre).

une autre façon de contourner cela est d'utiliser les formules R et d'alimenter le base de données (plus bas, après avoir calculé la partie conversion).

Oublier ce qui est dans pandas.rpy. Il est à la fois cassé et semble ignorer les fonctionnalités disponibles dans rpy2.

au plus tôt correction rapide de conversion avec ipython peut être transformé assez facilement en une conversion correcte. J'envisage d'en ajouter un à la base de codes rpy2 (avec plus de cloches et de sifflets), mais entre-temps, il suffit d'ajouter l'extrait suivant après toutes vos importations dans vos exemples de codes. Il convertira de manière transparente pandas' DataFrame objets dans rpy2 DataFrame chaque fois qu'un appel R est fait.

from collections import OrderedDict
py2ri_orig = rpy2.robjects.conversion.py2ri
def conversion_pydataframe(obj):
    if isinstance(obj, pandas.core.frame.DataFrame):
        od = OrderedDict()
        for name, values in obj.iteritems():
            if values.dtype.kind == 'O':
                od[name] = rpy2.robjects.vectors.StrVector(values)
            else:
                od[name] = rpy2.robjects.conversion.py2ri(values)
        return rpy2.robjects.vectors.DataFrame(od)
    elif isinstance(obj, pandas.core.series.Series):
        # converted as a numpy array
        res = py2ri_orig(obj) 
        # "index" is equivalent to "names" in R
        if obj.ndim == 1:
            res.names = ListVector({'x': ro.conversion.py2ri(obj.index)})
        else:
            res.dimnames = ListVector(ro.conversion.py2ri(obj.index))
        return res
    else:
        return py2ri_orig(obj) 
rpy2.robjects.conversion.py2ri = conversion_pydataframe

Maintenant, le code suivant va "juste":

r.plot(rpy2.robjects.Formula('c3~c2'), data)
# `data` was converted to an rpy2 data.frame on the fly
# and the a scatter plot c3 vs c2 (with "c2" and "c3" the labels on
# the "x" axis and "y" axis).

je note également que vous importez ggplot2 sans l'utiliser. Actuellement la conversion devra être explicitement demandée. Par exemple:

p = ggplot2.ggplot(rpy2.robjects.conversion.py2ri(data)) +\
    ggplot2.geom_histogram(ggplot2.aes_string(x = 'c3'))
p.plot()
7
répondu lgautier 2017-05-23 12:16:58

vous devez passer les étiquettes explicitement lorsque vous appelez le R. fonction de représentation graphique.

r.plot([1,2,3],[1,2,3], xlab="X", ylab="Y")

quand vous tracez dans R, Il saisit les étiquettes via deparse(substitute(x)) qui saisit essentiellement le nom de la variable de plot(testX, testY). Quand vous passez dans les objets python via rpy2, c'est un objet R anonyme qui s'apparente à ce qui suit dans R:

> deparse(substitute(c(1,2,3)))
[1] "c(1, 2, 3)"

c'est pour ça que tu as les étiquettes folles.

souvent, il est plus sain d'utiliser rpy2 pour push de données d'avant en arrière.

r.assign('testX', df.A)
r.assign('testY', df.B)
%R plot(testX, testY)

rdf = com.convert_to_r_dataframe(df)
r.assign('bob', rdf)
%R plot(bob$$A, bob$$B)

http://nbviewer.ipython.org/4734581/

6
répondu Dale Jung 2013-02-07 22:55:16

Utilisez rpy. la conversion fait partie des pandas donc vous n'avez pas besoin de le faire votressef http://pandas.pydata.org/pandas-docs/dev/r_interface.html

In [1217]: from pandas import DataFrame

In [1218]: df = DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C':[7,8,9]},
   ......:                index=["one", "two", "three"])
   ......:

In [1219]: r_dataframe = com.convert_to_r_dataframe(df)

In [1220]: print type(r_dataframe)
<class 'rpy2.robjects.vectors.DataFrame'>
5
répondu locojay 2013-02-02 01:23:46