[英]rpy2 fails for using 'np' package (error in dataframe conversion)
我使用的是rpy2 2.3.9版的Mac OS。
我試圖使用'np'R包將內核回歸模型擬合到我的數據中,該模型是從python預處理生成的。 'np'函數的用法與R中的基本lm
函數非常相似。然后我很難調用'np'函數,而使用lm函數就可以了。 請參閱以下玩具示例以解決我的問題。 我嘗試了三種回歸模型:'mgcv'軟件包中的lm
, gam
和'np'軟件包中的npreg
。 我首先使用從R數據集加載的mtcars
數據,然后使用形成為pandas數據幀的隨機生成的數據。
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
正如伊恩(Ian)指出的那樣,問題部分出在從熊貓的DataFrame到rpy2 / R的Dataframe的轉換上(問題的另一部分是從np的npreg()
(如您所指出的,其他建模函數也可以正常工作) 。
我們正在努力改善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)
您的問題是,當您將數據幀傳遞給convert_to_r_dataframe
,它將構成數據幀的每個向量的class屬性設置為“ 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"
如果您確實需要從python傳遞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"
請注意這一點,在現實生活中,向量的類可能會更復雜,以至於僅AsI,或者並非框架中的所有列都應該是數字,可能是字符或因子。
但是,上面的代碼現在可以正常工作(記住要打印或保存結果):
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.