python - rpy2 + 负二项式 glm

标签 python r glm rpy2

我正在尝试从 rpy2 调用 R glm.nb:

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中矩阵和数组的数据结构。下面用修复重现你在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

但是,可以使用三个修复方法:1) 使用矩阵(二维特殊类型的数组); 2) 等效定义的数组(指定 dim 参数); 3)矩阵转换。请注意:根据随机值,可能出现迭代限制警告,但仍会运行。

# 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由于both 统计的简单 glm() 出现了不同的错误,因此无法从我的脚本工作中有效地将 numpy 矩阵传递到 R 矩阵中和 MASS' 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 将数组对象转换为矩阵。记忆上面的第三个修复:

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

命令行解决方案

如果您的应用程序允许,只需从 Python 调用 R 建模脚本作为命令行子进程,绕过任何 rpy2 的需要。甚至根据需要传递参数:

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)) 

关于python - rpy2 + 负二项式 glm,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37175554/

相关文章:

随机重新排序(洗牌)矩阵的行?

r - R中glm逻辑回归模型的决定阈值

r - glmnet 变量重要性 | `vip` 与 `varImp`

python - 非轮询/非阻塞计时器?

python - 我怎样才能最有效地在 python 中解析这些参数?

python - Kivy如何使用Builder.load_file?

r - 从 R 向量的开头和结尾剪切元素

r 使用 gsub、trim 等修剪 data.frame 或 data.table 中的列

r - 如何在 R 中创建边际效应表?

python - 使用 Psycopg2 时,Postgres 在查询期间在几百秒后关闭连接