"ValueError: codes need to be between -1 and len(categories)-1" when extracting null values in rpy2

"ValueError: codes need to be between -1 and len(categories)-1" when extracting null values in rpy2

在使用 rpy2 和来自 synthpop R 包 (SD2011) 的内置数据集时,我收到此错误:

robjects.r('head(SD2011)')
# ...
# ValueError: codes need to be between -1 and len(categories)-1

我将问题深入到一个包含空条目的列中,例如这样做时我得到了同样的错误,但不是相邻的行或列:

robjects.r('SD2011[3, 27]')

我确认这是一个空值:

robjects.r('is.na(SD2011[, 27])')
# array([0, 0, 1, ..., 0, 0, 0], dtype=int32)

为什么 rpy2 没有优雅地处理这个问题?

Here's my notebook运行通过它。

Why is rpy2 not handling this gracefully?

这似乎是在使用 rpy2 版本 2.9.x(开发分支 default,未来 3.[=67)将 R 因子转换为 pandas 期间触发的错误=], 没有这个问题)。具体做的时候:

res = pandas.Categorical.from_codes(numpy.asarray(obj) - 1,
                                    categories = obj.do_slot('levels'),
                                    ordered = 'ordered' in obj.rclass)

R "factor" 对象是整数向量,每个整数在 "levels" 的关联向量中有一个索引。转换器只是简单地减一,因为 R 数组是单索引的,而 Python 数组是零索引的,但是只要有缺失值 (NA),这就会中断,因为 R 使用特定的整数来编码缺失的整数(一个极值)和 Python、numpy 和 pandas 对此没有等效项。

我打开了一个 issue to track this,与此同时,解决方法是将 R 侧的 NA 替换为一个级别(并称它们为 "missing" 或 "NA" ),将因子更改为字符串数组,或修改 pandas 转换器以获得 R 因子。例如:

robjects.r("""
  SD2011_nofactor <- SD2011 %>%
    dplyr::mutate_if(is.factor,
                     funs(as.character(.))
""")

(或使用rpy2's Pythonic interface to dplyr

注:

做的时候很少有事情成功发生:

robjects.r('SD2011[3, 27]')
  1. 评估 R 代码 SD2011[3, 27]
  2. 该评估的结果正在经历机器人级别的转换
  3. 该转换产生的对象显示在您的笔记本中

如果不确定,找出下面的Python个语句中哪一个是第一个失败的可以告诉它:

  1. 对R代码求值(加的TRUE是为了防止求值返回 x).

    robjects.r('x <- SD2011[3, 27]; TRUE')
    
  2. 获取从上面的评估中获得的对象 x 并将其绑定到 Python 符号(将应用转换)。

    x = robjects.r('x')
    
  3. 显示转换对象的文本表示

    repr(x)