2014-01-30 20 views
0

我在使用rpy2版本2.3.9的Mac OS上。rpy2使用'np'包失败(数据帧转换错误)

我正在尝试使用'np'R软件包将内核回归模型拟合到我的数据,这是从python预处理生成的。 'np'函数的使用与R中的基本函数lm非常相似。然后我很难调用'np'函数,而lm函数很好。请参阅以下玩具示例以了解我的问题。我尝试过三种回归模型,'mgcv'包中有lm,gam,'np'包中有npreg。我首先使用从R数据集加载的mtcars数据,然后使用随机生成的数据形成熊猫数据框。

import pandas as pd 
import pandas.rpy.common as com 
from rpy2.robjects.packages import importr 
import rpy2.robjects as ro 
import numpy as np 

r_ds = importr('datasets') 
r_stats = importr('stats') 
r_mgcv = importr('mgcv') 
r_np = importr('np') 

mtcars = r_ds.__rdata__.fetch('mtcars')['mtcars'] 

所有的三次回归方法mtcars工作:

r_stats.lm(ro.Formula('mpg ~ drat + wt'), data=mtcars) 
r_mgcv.gam(ro.Formula('mpg ~ s(drat) + wt'), data=mtcars) 
r_np.npreg(ro.Formula('mpg ~ drat + wt'), data=mtcars) 

然后,我产生一个熊猫数据帧,并将其转换至R数据框:

py_df = pd.DataFrame(np.random.randn(100,3), columns=['y', 'x_1', 'x_2']) 
r_df = com.convert_to_r_dataframe(py_df) 

现在奇怪的事情发生了:

r_stats.lm(ro.Formula('y ~ x_1 + x_2'), data=r_df) 
r_mgcv.gam(ro.Formula('y ~ s(x_1) + x_2'), data=r_df) 

工作,但

r_np.npreg(ro.Formula('y ~ x_1 + x_2'), data=r_df) 

失败,出现错误消息

Error in npregbw.default(xdat = xdat, ydat = ydat, bws = bws, ...) : 
'ydat' must be a vector 
--------------------------------------------------------------------------- 
RRuntimeError        Traceback (most recent call last) 
<ipython-input-22-0ec6b4eeaa3b> in <module>() 
----> 1 print r_base.summary(r_np.npreg(ro.Formula('y ~ x_1 + x_2'), data=r_df)) 

/Users/guest/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/rpy2/robjects/functions.pyc in __call__(self, *args, **kwargs) 
    84     v = kwargs.pop(k) 
    85     kwargs[r_k] = v 
---> 86   return super(SignatureTranslatedFunction, self).__call__(*args, **kwargs) 

/Users/guest/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/rpy2/robjects/functions.pyc in __call__(self, *args, **kwargs) 
    33   for k, v in kwargs.iteritems(): 
    34    new_kwargs[k] = conversion.py2ri(v) 
---> 35   res = super(Function, self).__call__(*new_args, **new_kwargs) 
    36   res = conversion.ri2py(res) 
    37   return res 

RRuntimeError: Error in npregbw.default(xdat = xdat, ydat = ydat, bws = bws, ...) : 
    'ydat' must be a vector 

回答

2

正如伊恩指出,问题的一部分是通过转换对源自熊猫DataFrames到rpy2 /的r Dataframes(问题的另一部分是从NP的npreg()(其他建模功能originiting做做工精细,正如你指出的话)。

有为了提高在rpy2-2.4.0工作,所以一定要报告问题(并可能尝试rpy2-2.4.0-dev的最新快照)。

一个更直接的(和简单的)解决方案可以如下获得(与rpy2-2.3.9和2.4.0-dev的测试,并且与熊猫0.13.0/R-3.0.2打补丁的):

# Your pandas DataFrame 
py_df = pd.DataFrame(np.random.randn(100,3), columns=['y', 'x_1', 'x_2']) 
r_df = com.convert_to_r_dataframe(py_df) 

该类型为AsIs。看到它可能更简单的方法是:

>>> [tuple(x.rclass) for x in r_df] 
[('AsIs',), ('AsIs',), ('AsIs',)] 

现在我们只是要删除的类AsIs

for col in r_df: 
    col.rclass = None 

载体可回到其基本类型:

>>> [tuple(x.rclass) for x in r_df] 
[('numeric',), ('numeric',), ('numeric',)] 

现在该呼叫正在运行,没有错误:

r_np.npreg(ro.Formula('y ~ x_1 + x_2'), data=r_df) 
+0

非常感谢,Igautier!这种“放下'AsIs'”功能将来会被添加到rpy2中(例如通过pandas2ri.activate())吗? –

+0

这个计划是为了改进'pandas2ri()'(它在rpy2-2.4.0-dev中已经可以说更好了),但是测试早期和归档错误报告是每个人都可以帮助我们覆盖大多数用例的。 – lgautier

1

你的问题是,当你通过数据帧convert_to_r_dataframe,它设置每个组成向量的类属性您的数据帧为“AsIs”:

In[56]: R = ro.r 

In [57]: R["print"](R.lapply(r_df,R["class"])) 
$y 
[1] "AsIs" 

$x_1 
[1] "AsIs" 

$x_2 
[1] "AsIs" 

当您正在传递的函数期望类是矢量类型。如果你直接R中创建数据帧,看看你会得到什么:

In [58]: R('''r_df2 <- data.frame(y=rnorm(100), x_1=rnorm(100), x_2=rnorm(100))''') 

In [59]: R["print"](R.lapply(R["r_df2"],R["class"])) 
$y 
[1] "numeric" 

$x_1 
[1] "numeric" 

$x_2 
[1] "numeric" 

如果你真的需要从蟒蛇的data.frame通过,你可以改变正是如此类:

In [60]: unAsIs = R('''function(x) { 
         class(x) <- "numeric" 
         return(x) 
         } ''') 

In [61]: r_df3 = R["as.data.frame"](R.lapply(r_df, unAsIs)) 

In [62]: R["print"](R.lapply(r_df3,R["class"])) 
$y 
[1] "numeric" 

$x_1 
[1] "numeric" 

$x_2 
[1] "numeric" 

注意这一点,在现实生活中,你的向量类可能更复杂,只是AsIs,或者不是你的框架中的所有列都应该是数字,它可能有些应该是字符或因子。

但是,你的代码上面现在工作(记得要打印或保存的结果):

In[63]: R["print"](r_np.npreg(ro.Formula('y ~ x_1 + x_2'), data=r_df3)) 

Regression Data: 100 training points, in 2 variable(s) 
        x_1  x_2 
Bandwidth(s): 0.6303934 9451331 

Kernel Regression Estimator: Local-Constant 
Bandwidth Type: Fixed 

Continuous Kernel Type: Second-Order Gaussian 
No. Continuous Explanatory Vars.: 2 
+0

所有调用像'R [“print”](x)''可以用更简单的方式写成'print(x)' – lgautier

+0

非常感谢,Ian!我从来不会在别处知道这个诀窍。 –