rpy2:提取变量中的模型公式无效(tmp,简化 = TRUE)

rpy2: Invalid Model formula in Extract Vars (tmp, simplify = TRUE)

我正在尝试通过 Python 中的 rpy2 接口使用 R "NADA" 包。最终目标是对左删失环境数据进行生存分析。对于其他功能,Python 和 R 之间似乎可以正确交互,并且我能够在 R 中执行测试功能,但是在通过 rpy2 尝试相同操作时出现错误。

这是我在 Python 中的代码。纯属虚构数据

from rpy2.robjects import FloatVector, BoolVector, FactorVector
from rpy2.robjects.packages import importr

nada = importr('NADA')
obs = FloatVector([1.0,2.0,3.0,5.0,56.0,1.0,4.0])
nds = BoolVector([False, True, True, True, True, False, True])
groups = FactorVector([1,0,1,0,1,1,0])

nada.cendiff(obs, nds, groups)

这是我收到的错误消息:

Traceback (most recent call last):
  File "C:/Users/XXXXXXX/rpy2_test.py", line 9, in <module>
    nada.cendiff(obs, nds, groups)
  File "C:\Program Files\Python35\lib\site-packages\rpy2\robjects\functions.py", line 178, in __call__
    return super(SignatureTranslatedFunction, self).__call__(*args, **kwargs)
  File "C:\Program Files\Python35\lib\site-packages\rpy2\robjects\functions.py", line 106, in __call__
    res = super(Function, self).__call__(*new_args, **new_kwargs)
rpy2.rinterface.RRuntimeError: Error in terms.formula(tmp, simplify = TRUE) : 
  invalid model formula in ExtractVars

此代码在 R 终端中运行良好:

library("NADA")
cendiff(c(1.0,2.0,3.0,5.0,56.0,1.0,4.0), c(FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE), factor(c(1,0,1,0,1,1,0)))

我尝试在列出的 rpy2 错误行中添加一些打印行,并怀疑 rpy2 在将它们发送到函数时从因子向量中删除水平可能存在问题。然而,我在新的领域,这可能只是一个转移注意力的问题。

如果有人能提供一些见解或提供替代方案,我将不胜感激。我有很多数据处理编码在 Python 中,所有 R 都不是一个好的选择,但 R 有更多的分析选项,所以我希望 rpy2 能做到这一点。

当怀疑rpy2是否and/or其转换规则之一 正在做一些意想不到的事情,检查起来相对容易。 例如这里:

from rpy2.robjects.vectors import FactorVector
from rpy2.robjects import r, globalenv

# factor with rpy2
groups = FactorVector([1,0,1,0,1,1,0])
# bind it to symbol in R's GlobalEnv
globalenv['groups_rpy2'] = groups

# it is the same as building the factor in R ?
r("""
    ...: groups <- factor(c(1,0,1,0,1,1,0))
    ...: print(identical(groups, groups_rpy2))
    ...: """)
[1]
 TRUE

# apparently so

我怀疑这是由于您正在使用的 R 库中使用了(未评估的)表达式语句,并且 rpy2 正在传递匿名 R 对象。我快速浏览了该代码,我可以看到:

setMethod("cendiff", 
          signature(obs="numeric", censored="logical", groups="factor"), 
          cencen.vectors.groups)

cencen.vectors.groups =
function(obs, censored, groups, ...)
{
    cl = match.call()
    f = substitute(Cen(a, b)~g, list(a=cl[[2]], b=cl[[3]], g=cl[[4]]))
    f = as.formula(f)
    environment(f) = parent.frame()
    callGeneric(f, ...)
}

解决此问题的一种方法是将您的对象绑定到 R namespace/environment 中的符号并评估该命名空间中的调用。它可以在任何 R 环境中完成,但如果使用 "GlobalEnv"(在这种情况下,请记住 GlobalEnv 的内容会一直存在,直到嵌入式 R 关闭):

from rpy2.robjects.packages import importr
base = importr('base')
# bind to R symbols
globalenv["obs"] = obs
globalenv["nds"] = nds
globalenv["groups"] = groups

# make the call 
nada.cendiff(base.as_symbol('obs'),
             base.as_symbol('nds'),
             base.as_symbol('groups'))

(参见 as_symbol 的其他用法)