【问题标题】:Minimal example of rpy2 regression using pandas data frame使用 pandas 数据框的 rpy2 回归的最小示例
【发布时间】:2015-09-04 11:54:54
【问题描述】:

使用 pandas 数据框进行线性回归的推荐方法是什么(如果有)?我可以做到,但我的方法似乎很复杂。我是否让事情变得不必要的复杂?

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 时(如 here 所述),我得到了

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

【问题讨论】:

  • 你使用的是什么版本的rpy2
  • 我已更新我的问题以添加此信息。
  • 我在数据帧转换方面遇到了类似的问题,但我不得不使用非 rpy2 函数。原来你必须在调用pandas2ri.py2ri(dataframe)之前执行pandas2ri.activate()

标签: r pandas rpy2


【解决方案1】:

在调用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

【讨论】:

    【解决方案2】:

    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
    

    【讨论】:

    • 不错。谢谢你。我知道我最初的尝试可能过于复杂。
    • @l Unutbu 的答案看起来非常直观,因为无需在 R 命名空间中分配 DF 或使用 as_symbol。这种将 pandas DF 直接传递给 r 函数的方法是否像 ununtbu 的示例支持的语法一样,还是会被弃用?我仔细阅读文档并没有得到答案。
    • @KGS :我的回答侧重于使数据帧转换不起作用的说法无效。为此,我尽可能保持问题中的代码不变。我不认为@unutbu 的答案很快就会失效:R 的stats::lm 一直接受参数data,我认为它不会轻易改变。
    【解决方案3】:

    我可以通过概述如何检索系数表的特定元素来添加到unutbu's answer,包括关键的p-值。

    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
    

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 2019-03-14
      • 2013-11-28
      • 2019-09-19
      • 2013-10-23
      • 2019-08-13
      • 1970-01-01
      • 2017-10-10
      • 2020-12-23
      相关资源
      最近更新 更多