2016-05-12 19 views
3

私はrpy2からR glm.nbを呼び出すようにしようとしています:rpy2 +負の二項GLM

from rpy2 import robjects 
from rpy2.robjects.packages import importr 

MASS = importr('MASS') 
stats = importr('stats') 

def glm_nb(x,y): 
    formula = robjects.Formula('y~x') 
    env = formula.environment 
    env["x"] = x 
    env["y"] = y 
    fitted = MASS.glm_nb(formula) 
#  fitted = stats.glm(formula) 
    return fitted 

テスト:

N = 100 
x = np.random.rand(N) 
y = x + np.random.poisson(10, N) 
fitted = glm_nb(x, np.round(y)) 

はエラーを返します:

104   for k, v in kwargs.items(): 
    105    new_kwargs[k] = conversion.py2ri(v) 
--> 106   res = super(Function, self).__call__(*new_args, **new_kwargs) 
    107   res = conversion.ri2ro(res) 
    108   return res 

RRuntimeError: Error in x[good, , drop = FALSE] * w : non-conformable arrays 

しかし、私はシンプルな実行したときglm正常に実行されます。どのような問題があり、どのようにして問題をデバッグすることができますか?

Rのエラーと修正

答えて

1

本質的な問題は、以下の修正とRにrpy2に修正を複製するの挑戦をあなたのエラーを再現し、作業溶液R.における行列と配列のデータ構造を含み、

library(MASS) 

# ARRAY 
x <- array(rnorm(100)) 
y <- as.integer(x) + array(rpois(100, 10)) 

model2 <- glm.nb(y~x) 

Error in x[good, , drop = FALSE] * w : non-conformable arrays

しかし、3つの修正プログラムが利用可能である:マトリックス(アレイの二次元特殊タイプ)の1)使用。 2)同等に定義された配列(dim引数を指定)。 3)マトリックス変換。注記:反復制限の警告はランダム値に応じて表示されますが、実行されるのはです。別のエラーが両方のstatのシンプルglm()とMASSのために出てくるよう

# MATRIX 
x <- matrix(rnorm(100)) 
y <- as.integer(x) + matrix(rpois(100, 10)) 

model1 <- glm.nb(y~x) 

# EQUIVALENT ARRAY 
x <- array(rnorm(100),c(100,1)) 
y <- as.integer(x) + matrix(rpois(100, 10),c(100,1)) 

model2 <- glm.nb(y~x) 

# EXPLICIT MATRIX CONVERSION (USED IN WORKING SOLUTION) 
x <- as.matrix(array(rnorm(100))) 
y <- as.integer(x) + as.matrix(array(rpois(100, 10))) 

model3 <- glm.nb(y~x) 

チャレンジ

Pythonのrpy2は、スクリプトの私の働きから効果的にR行列にnumpyの行列を渡しません'glm.nb()

import numpy as np 
from rpy2 import robjects 
from rpy2.robjects.packages import importr 
from rpy2.robjects.numpy2ri import numpy2ri 
MASS = importr('MASS') 

#rpy2 + negative binomial glm 
stats = importr('stats') 

def glm_nb(x,y): 
    formula = robjects.Formula('y~x') 
    env = formula.environment 
    env["x"] = x 
    env["y"] = y  
    fitted = MASS.glm_nb(formula) 
# fitted = stats.glm(formula) 
    return fitted 

N = 100 
x = np.random.rand(N) 
x = np.asmatrix(x)       # PYTHON CONVERSION TO MATRIX 
r_x = numpy2ri(x) 

# REPLACED NP.ROUND FOR AS.TYPE() TO COMPARE WITH R 
y = x.astype(int) + np.random.poisson(10, N) 
y = np.asmatrix(y)       # PYTHON CONVERSION TO MATRIX 
r_y = numpy2ri(y) 

fitted = glm_nb(r_x, r_y) 

rpy2.rinterface.RRuntimeError: Error in glm.fitter(x = X, y = Y, w = w, start = start, etastart = etastart, : object 'fit' not found

でもnumpy2ri.activate()がnumpyの行列の変換に失敗しました:

from rpy2.robjects import numpy2ri 
robjects.numpy2ri.activate() 
r_x = numpy2ri.ri2py(x) 
r_y = numpy2ri.ri2py(y) 

NotImplementedError: Conversion 'ri2py' not defined for objects of type '<class 'numpy.matrixlib.defmatrix.matrix'>'


作業溶液

単にrobjects.r()とのインターフェースおよびRは、行列に配列オブジェクトが働い変換しています。上述した第3の修正を思い出してください:

N = 100 
x = np.random.rand(N) 
r_x = numpy2ri(x) 

y = x.astype(int) + np.random.poisson(10, N) 
r_y = numpy2ri(y) 

from rpy2.robjects import r 
r.assign("y", r_y) 
r.assign("x", r_x) 
r("x <- as.matrix(x)") 
r("y <- as.matrix(y)") 
r("res <- glm.nb(y~x)") 

r_result = r("res[1:5]") 

# CONVERSION INTO PY DICTIONARY  
from rpy2.robjects import pandas2ri 
pandas2ri.activate() 
pyresult = pandas2ri.ri2py(r_result) 
print(pyresult)      # OUTPUTS COEFF, RESID, FITTED VALS, EFFECTS, R 

# OR OLDER DEPRECATED CONVERSION 
import pandas.rpy.common as com 
pyresult = com.convert_robj(r_result) 
print(pyresult)      # OUTPUTS COEFF, RESID, FITTED VALS, EFFECTS, R 

コマンドラインソリューション

アプリケーションで許容した場合、単純にrpy2の必要性をバイパスして、コマンド・ライン・サブプロセスとしてPythonからRモデリングスクリプトを呼び出しても、合格必要に応じて引数:何が起こっている

from subprocess import Popen, PIPE 

command = 'Rscript.exe' 
path2Script = 'path/to/Script.R'  
args = ['arg1', 'arg2', 'arg3'] 

cmd = [command, path2Script] + args 

p = Popen(cmd,stdin= PIPE, stdout= PIPE, stderr= PIPE)    
output,error = p.communicate() 

if p.returncode == 0:    
    print('R OUTPUT:\n {0}'.format(output))    
else:     
    print('R ERROR:\n {0}'.format(error)) 
1

は、基礎となるRのコードが期待されていることである「ベクトル」の配列が、Pythonオブジェクトが配列されているということ。

簡単な修正は、あなたが望む/期待しているパッケージMASSのR関数を与えることです。あなたのテストに次の行を変更することができます。

fitted = glm_nb(x, np.round(y)) 

...これに:

import array 
fitted = glm_nb(array.array('f', x), array.array('f', np.round(y))) 

...またはこれに:

from rpy2.robjects.vectors import FloatVector 
fitted = glm_nb(FloatVector(x), FloatVector(np.round(y))) 
関連する問題