2015-06-18 11 views
14

Was ist die empfohlene Methode (falls vorhanden) für die lineare Regression mit einem Pandas-Datenrahmen? Ich kann es, aber meine Methode scheint sehr aufwendig. Mache ich Dinge unnötig kompliziert?Minimales Beispiel für die rpy2-Regression mit Pandas-Datenrahmen

Der Code R, zum Vergleich:

x <- c(1,2,3,4,5) 
y <- c(2,1,3,5,4) 
M <- lm(y~x) 
summary(M)$coefficients 
      Estimate Std. Error t value Pr(>|t|) 
(Intercept)  0.6 1.1489125 0.522233 0.6376181 
x    0.8 0.3464102 2.309401 0.1040880 

Nun, mein Python (2.7.10), rpy2 (2.6.0) und Pandas (0.16.1) Version:

import pandas 
import pandas.rpy.common as common 
from rpy2 import robjects 
from rpy2.robjects.packages import importr 

base = importr('base') 
stats = importr('stats') 

dataframe = pandas.DataFrame({'x': [1,2,3,4,5], 
           'y': [2,1,3,5,4]}) 

robjects.globalenv['dataframe']\ 
    = common.convert_to_r_dataframe(dataframe) 

M = stats.lm('y~x', data=base.as_symbol('dataframe')) 

print(base.summary(M).rx2('coefficients')) 

      Estimate Std. Error t value Pr(>|t|) 
(Intercept)  0.6 1.1489125 0.522233 0.6376181 
x    0.8 0.3464102 2.309401 0.1040880 

Übrigens, ich bekomme ein FutureWarning über den Import von pandas.rpy.common. Allerdings, wenn ich die pandas2ri.py2ri(dataframe) versucht, einen Datenrahmen von Pandas R zu umwandeln (wie here erwähnt), erhalte ich

NotImplementedError: Conversion 'py2ri' not defined for objects of type '<class 'pandas.core.series.Series'>' 
+0

Welche Version von 'rpy2' verwenden Sie? – joris

+0

Ich habe meine Frage aktualisiert, um diese Informationen hinzuzufügen. – mjandrews

+2

Ich hatte ähnliche Probleme mit der Konvertierung von Datenrahmen, aber ich musste nicht rpy2 Funktionen verwenden. Es stellt sich heraus, dass Sie 'pandas2ri.activate()' ausführen müssen, bevor Sie 'pandas2ri.py2ri (dataframe)' ' – shibumi

Antwort

12

Die R und Python sind nicht genau identisch, weil Sie einen Datenrahmen in Python/rpy2 während Sie bauen verwenden Vektoren (ohne Datenrahmen) in R.

Andernfalls wird die Umwandlung Versand mit rpy2 hier arbeiten zu werden:

from rpy2.robjects import pandas2ri 
pandas2ri.activate() 
robjects.globalenv['dataframe'] = dataframe 
M = stats.lm('y~x', data=base.as_symbol('dataframe')) 

das Ergebnis:

>>> print(base.summary(M).rx2('coefficients')) 
      Estimate Std. Error t value Pr(>|t|) 
(Intercept)  0.6 1.1489125 0.522233 0.6376181 
x    0.8 0.3464102 2.309401 0.1040880 
+0

Nice aufrufen. Vielen Dank. Ich wusste, dass mein erster Versuch die Dinge wahrscheinlich überkompensierte. – mjandrews

+0

@l Die Antwort von Unutbu sieht sehr intuitiv aus, da es nicht notwendig ist, den DF im R-Namespace zuzuweisen oder as_symbol zu verwenden. Ist diese Methode, einen Pandas-DF direkt an die r-Funktion zu übergeben, wie die Beispiel-unterstützte Syntax von ununtbu, oder wird sie veraltet sein? Meine Durchsicht durch die Dokumentation hat keine Antwort ergeben. – KGS

+0

@KGS: Meine Antwort konzentriert sich auf die Ungültigkeit der Behauptung, dass die Konvertierung von Datenrahmen nicht funktioniert. Um dies zu tun, habe ich den Code in der Frage so weit wie möglich unverändert gelassen.Ich sehe nicht, dass @unutbus Antwort bald ungültig wird: Rs 'stats :: lm' hat immer einen Parameter' data' akzeptiert, und ich denke nicht, dass es sich leicht ändern würde. – lgautier

19

Nach dem Aufruf pandas2ri.activate() passieren einige Konvertierungen von Pandas-Objekten zu R-Objekten automatisch. Zum Beispiel können Sie

M = R.lm('y~x', data=df) 

statt

robjects.globalenv['dataframe'] = dataframe 
M = stats.lm('y~x', data=base.as_symbol('dataframe')) 

import pandas as pd 
from rpy2 import robjects as ro 
from rpy2.robjects import pandas2ri 
pandas2ri.activate() 
R = ro.r 

df = pd.DataFrame({'x': [1,2,3,4,5], 
        'y': [2,1,3,5,4]}) 

M = R.lm('y~x', data=df) 
print(R.summary(M).rx2('coefficients')) 

ergibt

  Estimate Std. Error t value Pr(>|t|) 
(Intercept)  0.6 1.1489125 0.522233 0.6376181 
x    0.8 0.3464102 2.309401 0.1040880 
1

verwende ich zu unutbu's answer durch umreißt hinzufügen können, wie bestimmte Elemente der abrufen Koeffiziententabelle includin g, entscheidend, die p -Werte.

def r_matrix_to_data_frame(r_matrix): 
    """Convert an R matrix into a Pandas DataFrame""" 
    import pandas as pd 
    from rpy2.robjects import pandas2ri 
    array = pandas2ri.ri2py(r_matrix) 
    return pd.DataFrame(array, 
         index=r_matrix.names[0], 
         columns=r_matrix.names[1]) 

# Let's start from unutbu's line retrieving the coefficients: 
coeffs = R.summary(M).rx2('coefficients') 
df = r_matrix_to_data_frame(coeffs) 

Dies lässt uns mit einem Datenrahmen, die wir in gewohnter Weise zugreifen können:

In [179]: df['Pr(>|t|)'] 
Out[179]: 
(Intercept) 0.637618 
x    0.104088 
Name: Pr(>|t|), dtype: float64 

In [181]: df.loc['x', 'Pr(>|t|)'] 
Out[181]: 0.10408803866182779 
Verwandte Themen