使用pandas数据框的rpy2回归的最小示例

21

有没有推荐的方法(如果有的话)可以使用pandas dataframe进行线性回归?我可以做到,但是我的方法似乎非常复杂。我是否在使事情变得不必要的复杂?

与之相比,R代码如下:

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

现在,我的Python(2.7.10)、rpy2(2.6.0)和pandas(0.16.1)版本:

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

顺便提一下,我在导入pandas.rpy.common时收到了一个FutureWarning。然而,当我尝试使用pandas2ri.py2ri(dataframe)将来自pandas的数据框转换为R(正如这里所述),我得到了以下结果。

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

你使用的 rpy2 版本是什么? - joris
我已经更新了我的问题,添加了这些信息。 - mjandrews
2
我在数据框转换方面遇到了类似的问题,但是我不得不使用非rpy2函数。结果发现,在调用pandas2ri.py2ri(dataframe)之前,必须执行pandas2ri.activate() - shibumi
3个回答

28

调用pandas2ri.activate()后,一些从Pandas对象到R对象的转换会自动发生。例如,您可以使用

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

代替
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'))

产出
            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

很棒的回答!R = ro.r 是什么意思? - undefined

14

R和Python并不完全相同,因为在Python / rpy2中构建数据框,而在R中则使用向量(不使用数据框)。

否则,随附rpy2的转换似乎在此处起作用:

from rpy2.robjects import pandas2ri
pandas2ri.activate()
robjects.globalenv['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

好的,谢谢。我知道我的初步尝试可能过于复杂化了。 - mjandrews
1
@l Unutbu的答案看起来非常直观,因为不需要在R命名空间中分配DF或使用as_symbol。像Unutbu的示例一样直接将pandas DF传递给r函数的这种方法是否是支持的语法,还是将被弃用?我查阅了文档,但没有找到答案。 - KGS
@KGS:我的回答重点在于否定数据框转换不起作用的说法。为此,我尽可能保持了问题中的代码不变。我认为@unutbu的答案短时间内不会失效:R的stats::lm一直接受参数data,我不认为它会轻易改变。 - lgautier

4

我可以通过概述如何检索系数表中特定元素(包括关键的p值)来补充unutbu的答案

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)

这给我们留下了一个DataFrame,我们可以以正常的方式访问它:
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接