rpy2、rpart在Python与R之间传递数据时遇到问题
我正在尝试通过RPY2在Python 2.6.5和R 10.0中运行rpart。
我在Python中创建了一个数据框,然后把它传过去,但我遇到了一个错误,错误信息是:
Error in function (x) : binary operation on non-conformable arrays
Traceback (most recent call last):
File "partitioningSANDBOX.py", line 86, in <module>
model=r.rpart(**rpart_params)
File "build/bdist.macosx-10.3-fat/egg/rpy2/robjects/functions.py", line 83, in __call__
File "build/bdist.macosx-10.3-fat/egg/rpy2/robjects/functions.py", line 35, in __call__
rpy2.rinterface.RRuntimeError: Error in function (x) : binary operation on non-conformable arrays
有没有人能帮我看看我哪里做错了,导致出现这个错误?
我代码中相关的部分是:
import numpy as np
import rpy2
import rpy2.robjects as rob
import rpy2.robjects.numpy2ri
#Fire up the interface to R
r = rob.r
r.library("rpart")
datadict = dict(zip(['responsev','predictorv'],[cLogEC,csplitData]))
Rdata = r['data.frame'](**datadict)
Rformula = r['as.formula']('responsev ~.')
#Generate an RPART model in R.
Rpcontrol = r['rpart.control'](minsplit=10, xval=10)
rpart_params = {'formula' : Rformula, \
'data' : Rdata,
'control' : Rpcontrol}
model=r.rpart(**rpart_params)
这两个变量cLogEC和csplitData是浮点类型的numpy数组。
另外,我的数据框看起来是这样的:
In [2]: print Rdata
------> print(Rdata)
responsev predictorv
1 0.6020600 312
2 0.3010300 300
3 0.4771213 303
4 0.4771213 249
5 0.9242793 239
6 1.1986571 297
7 0.7075702 287
8 1.8115750 270
9 0.6020600 296
10 1.3856063 248
11 0.6127839 295
12 0.3010300 283
13 1.1931246 345
14 0.3010300 270
15 0.3010300 251
16 0.3010300 246
17 0.3010300 273
18 0.7075702 252
19 0.4771213 252
20 0.9294189 223
21 0.6127839 252
22 0.7075702 267
23 0.9294189 252
24 0.3010300 378
25 0.3010300 282
而公式看起来是这样的:
In [3]: print Rformula
------> print(Rformula)
responsev ~ .
1 个回答
5
这个问题和R语言中的rpart代码有关,具体来说,是下面这段代码,特别是最后一行:
m <- match.call(expand.dots = FALSE)
m$model <- m$method <- m$control <- NULL
m$x <- m$y <- m$parms <- m$... <- NULL
m$cost <- NULL
m$na.action <- na.action
m[[1L]] <- as.name("model.frame")
m <- eval(m, parent.frame())
。
解决这个问题的一种方法是避免进入那段代码(见下文),或者可以尝试从Python构建一个嵌套的评估(这样parent.frame()就能正常工作)。这并不像人们希望的那么简单,但也许我将来会找时间让它变得更简单。
from rpy2.robjects import DataFrame, Formula
import rpy2.robjects.numpy2ri as npr
import numpy as np
from rpy2.robjects.packages import importr
rpart = importr('rpart')
stats = importr('stats')
cLogEC = np.random.uniform(size=10)
csplitData = np.array(range(10), 'i')
dataf = DataFrame({'responsev': cLogEC,
'predictorv': csplitData})
formula = Formula('responsev ~.')
rpart.rpart(formula=formula, data=dataf,
control=rpart.rpart_control(minsplit = 10, xval = 10),
model = stats.model_frame(formula, data=dataf))